함수에서 malloc 사용후 free로 메모리 해제안해줘도 되지 않나

innu의 이미지

너무 기초적인 질문일지 싶습니다.
말그대로입니다.

#include <stdio.h>
#include <string.h>
#include <stdclib.h>

char *re_str(char *ptr);

int main() {
   char *p;

   p="We are the world !!!";
   printf("%s\n",re_str(p));
   return 0;
}

char *re_str(char *ptr) {
   char *rev;
   int i,j;
   
   i=strlen(ptr)-1;
   j=0;

   rev=(char *)malloc(strlen(ptr));

   for ( ; i>=0; i--) {
      rev[j]=*(ptr+i);
      j++;
   }

   rev[j]='\0';

   return rev;
   free(rev);           /* 없어도 상관없지 않나요? */
}


/* 결과 */
/* !!! dlrow eht era eW */

고정된 문자열을 거꾸로 출력하는 함수입니다.
만약 re_str() 없이 main으로 들어가 버리면 free 해줘야 겠지만 함수로 모듈화시키면 함수호출이 끝남과 동시에 메모리에서 해제되니까 free 쓸필요가 없지 않나요?

정태영의 이미지

nullnull wrote:
너무 기초적인 질문일지 싶습니다.
말그대로입니다.

char *re_str(char *ptr) {
.
.
   rev=(char *)malloc(strlen(ptr));
.
.
   return rev;
   free(rev);           /* 없어도 상관없지 않나요? */
}

고정된 문자열을 거꾸로 출력하는 함수입니다.
만약 re_str() 없이 main으로 들어가 버리면 free 해줘야 겠지만 함수로 모듈화시키면 함수호출이 끝남과 동시에 메모리에서 해제되니까 free 쓸필요가 없지 않나요?

흠 우선.. 위의 함수에서..

return rev 이후의 코드는 실행되지 않습니다..
그렇기 때문에 free는 이루어 지지 않습니다..

그리고 함수가 호출됐을때 할당됐다가.. 함수가 끝나면서 파괴되는 메모리는..
static 으로 선언한 것들이지 malloc같은걸로 동적할당 한 것들이 아닙니다 ;)

그렇기 때문에 꼭 풀어줘야 하며.. 위와 같이 쓰면 메모리는 셀 수 밖에 없습니다..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

bugiii의 이미지

   return rev;         //??? ??? ???
   free(rev);           /* 없어도 상관없지 않나요? */ 

먼저 return 문장 다음의 free() 함수는 절대 호출되지 않습니다. 아마 잠깐 혼동하신 듯 하구요...

malloc 으로 할당 받은 메모리는 함수가 리턴되어도 저쪽 어딘가 힙 메모리에 남아 있습니다. 그 할당 받은 메모리가 함수 내부에서만 사용되었다면 함수안에서 free 하시는 것이 맞고, 만약 그 메모리가 함수가 끝나도 유지되어야 한다면 함수를 호출한 쪽에서 free하는 것이 대부분입니다.

kslee80의 이미지

malloc() 한 메모리에 대해서 OS 에서 알아서 해제해 준다는 이유로
free() 를 하지 않는 것은 안좋은 습관이라고 봅니다.

최근의 *nix 계열이나 Windows 계열 OS 에서 프로그램 종료시
알아서 사용한 메모리를 해제해 준다고 해서 그런 식으로 코딩했다가,
그런 작업을 해 주지 않는 OS 로 포팅해야 할 일이 생겼을때는 끔찍하겠죠 -.-;;

advanced의 이미지

윗분들 말씀처럼 free 가 필요가 없습니다.

그리고 만약 실행이 되게 return 위로 free 를 올린다고 한다면

함수의 return 값으로 포인터를 받는곳에서는 해채된 주소의 포인터를

받게 되므로 segment fault 가 날껍니다.

그리고 여담이지만 malloc() 등으로 heap 영역에 할당한 동적메모리는

함수가 종료된다고 해채되는것이 아닙니다

함수내에서의 pointer 변수가 해체되는것을 착각하신듯 합니다.

heap 영역의 주소를 가르키는 지역변수가 사라진다고 해서

heap 영역에 할당한 메모리 영역이 해체되는것은 아니지요

물론 프로세서가 종료되면 모두 해체가 됩니다만...

- advanced -

ifyou의 이미지

free가 필요없는 것이 아니고, 해서는 안되는 경우겠죠..

모두들 설명을 잘해 주셨으니, 같은 내용 두번 말할 필요는 없겠고..

위의 함수는 결국 디자인의 문제일 것 같습니다. 함수를 호출할때

아예 메모리를 넘겨주던지, 내부에서 malloc한 메모리를 리턴한다면

외부에서 free를 해 주던지....

관련성은 좀 적지만 이글을 한번 참조해 보시기 바랍니다.

http://bbs.kldp.org/viewtopic.php?t=29126&highlight=ctime

죠커의 이미지

kslee80 wrote:
malloc() 한 메모리에 대해서 OS 에서 알아서 해제해 준다는 이유로
free() 를 하지 않는 것은 안좋은 습관이라고 봅니다.

정말인가요? 그럼 윈도 NT에서도 왜 메모리 누수를 확인하는 툴이 있는건가요?

RisaPapa님의 말씀에도 메모리 리크가 있는 프로그램을 fastcgi에서 쓸수 없다는 부분도 있었습니다.

전 이 부분이 의아하네요.

그럼 실행 순간이 짧은 프로그램이라면 메모리 누수에 대한 고민을 안해도 되는 것입니까?

죠커의 이미지

nullnull wrote:
너무 기초적인 질문일지 싶습니다.
말그대로입니다.

#include <stdio.h>
#include <string.h>
#include <stdclib.h>

char *re_str(char *ptr);

int main() {
   char *p;

   p="We are the world !!!";
   printf("%s\n",re_str(p));
   return 0;
}

char *re_str(char *ptr) {
   char *rev;
   int i,j;
   
   i=strlen(ptr)-1;
   j=0;

   rev=(char *)malloc(strlen(ptr));

   for ( ; i>=0; i--) {
      rev[j]=*(ptr+i);
      j++;
   }

   rev[j]='\0';

   return rev;
   free(rev);           /* 없어도 상관없지 않나요? */
}


/* 결과 */
/* !!! dlrow eht era eW */

고정된 문자열을 거꾸로 출력하는 함수입니다.
만약 re_str() 없이 main으로 들어가 버리면 free 해줘야 겠지만 함수로 모듈화시키면 함수호출이 끝남과 동시에 메모리에서 해제되니까 free 쓸필요가 없지 않나요?

잘못된 프로그램입니다. free(rev)가 return뒤에 있어서 실행되지 않습니다. 그렇다고 free의 시점을 앞으로 당긴다면 반환값이 없을 겁니다. 저 같으면 main에서 해제할 내용이니(main이 그 값을 읽어들여서 확인한 후에야 해제할 수 있으니깐요.) main에서 할당하는게 어떨까 싶네요.

어떠한 경우든 malloc과 free의 짝은 맞아야 합니다.

akbar의 이미지

CN wrote:
전 이 부분이 의아하네요.

그럼 실행 순간이 짧은 프로그램이라면 메모리 누수에 대한 고민을 안해도 되는 것입니까?

예 안해도됩니다. 적어도 리눅스에서는 안해도 됩니다.

무한 루프문에서 큰 데이타 덩어리를 malloc 해 보시기 바랍니다.

cjh의 이미지

CN wrote:
RisaPapa님의 말씀에도 메모리 리크가 있는 프로그램을 fastcgi에서 쓸수 없다는 부분도 있었습니다.

전 이 부분이 의아하네요.

그럼 실행 순간이 짧은 프로그램이라면 메모리 누수에 대한 고민을 안해도 되는 것입니까?

fastcgi는 CGI를 실행할 때 마다 fork()하는게 아니라 떠 있는 상태에서 재시작하도록 하는 것으로 알고 있습니다. 같은 내용이 반복 실행되고 오래 떠 있으니까 메모리 누수가 있으면 점점 차지하는 메모리가 늘어나서 문제가 되죠. mod_perl이나 mod_php같은 것도 동일한 방식으로 동작하므로 메모리 문제에 민감할 수 밖에 없습니다. 물론 keep-alive를 끄고 MaxRequestsPerChild를 1로 두면 매번 다시 뜨니까 그런 문제가 없어지겠지만 상당히 느려지죠.

짧게 실행하고 바로 끝나는 프로그램은 이런 영향을 덜 받는 건 맞습니다. OS에서 해제해 주니까요(좋은 OS라면!)
하지만 그렇다고 malloc()/free()를 안하는건 좋은 습관이 아니죠. 차라리 스크립트 언어를 사용하는게 낫겠습니다.

--
익스펙토 페트로눔

죠커의 이미지

좋은 운영체제들은 프로그램이 종료될때 해제를 해주는 군요.

그렇다고 해서 프로그램이 처리못한 일을 운영체제가 처리하게 하는 일은 바보같은 일인 것 같습니다. cjh님 말처럼 차라리 스크립트 언어를 사용하는게 낫겠네요.

그런데 akbar님의 이야기는 현재 사용하지 않는 공간들을 운영체제가 페이징을 잘 해준다는 이야기로 받아들여도 되는 것입니까? 또 무한 루프중에 계속 malloc을 실행한다는 것인가요 아니면 한번 malloc을 시켜두고 종료를 하지 않는다는 말이신가요? 장기적으로 운영체제의 페이징에 부담이 될 가능성은 없는 것인가요?

winner의 이미지

유명한 책들 가운데에서도 동적 memory 할당해놓고, 해제를 안 해주는 경우를 보곤 합니다. (예 : STL Tutorial & Refernce Guide - 그림문자.)

이에 대해서 C/C++ 표준의 정의가 어떻게 되어 있는지 아시는 분은 없나요?

또한 file descriptor 에 대해서 역시 답변주시면 감사하겠습니다.

onemind555의 이미지

void func() {

std::auto_ptr kkk(new char[3323]);
}

C++라이브러리 사용 하는것이 가장 편합니다.

-----------^^ ^^ ^^ ^^ ^^ ----------
..........................................................

bugiii의 이미지

std::auto_ptr은 배열의 동적할당을 지원하지 않습니다. --- 급하신 마음에 예제를 잘못 적용하신 듯 :wink: auto_ptr의 소멸자는 delete를 호출합니다. delete []를 호출하지 않으면... C++에서 배열 형태는 std::vector를 쓰는 것이 좋습니다.

그리고, 질문하신 분은 함수의 리턴값으로 malloc한 메모리를 원하고 있습니다. C++ 에서는 새로운 auto_ptr의 특징으로 함수의 리턴값으로 다음과 같이 사용하는 것이 좋다고 합니다. (프록시를 사용해서...)

auto_ptr<myT> make_myT()
{
    auto_ptr<myT> result( new myT );
    ....
    return( result );
}

void test()
{
    auto_ptr<myT> t1( make_myT() ); // t1 소멸시 메모리 해제
    ....
    make_myT(); // 변수로 받지 않아도 문장이 끝나면 자동으로 메모리 해제
    ....
}
onemind555의 이미지

... 실 수 했네요... 급하게 올리다 보니....

배열을 자동 해제 할때는 boost라이브러리에 있는 라이브러리를 써야 하죠....array_ptr이었던가...

-----------^^ ^^ ^^ ^^ ^^ ----------
..........................................................

onemind555의 이미지

return rev; 
   free(rev);           /* 없어도 상관없지 않나요? */ 

없어도 상관 없는게 아니고 있으나 마나 입니다...
컴파일러가 warnning을 표시 할 텐데요...

-----------^^ ^^ ^^ ^^ ^^ ----------
..........................................................

eungkyu의 이미지

CN wrote:
좋은 운영체제들은 프로그램이 종료될때 해제를 해주는 군요.

그렇다고 해서 프로그램이 처리못한 일을 운영체제가 처리하게 하는 일은 바보같은 일인 것 같습니다. cjh님 말처럼 차라리 스크립트 언어를 사용하는게 낫겠네요.


좋은 운영체제라기보다는 진짜 운영체제는 잘 헤제를 해주죠. 운영체제의 가장 중요한 역할중 하나는 resource 관리입니다.
죠커의 이미지

winner wrote:
유명한 책들 가운데에서도 동적 memory 할당해놓고, 해제를 안 해주는 경우를 보곤 합니다. (예 : STL Tutorial & Refernce Guide - 그림문자.)

혹시 페이지가 기억나시는가요? 알려주시면 참고해봐야겠습니다. :-)
(어떤 부분인지 기억나시지 않는다면 굳이 찾을 필요는 없습니다.^^)

winner의 이미지

강컴에서 2판 번역서를 검색해서 목차를 확인해보면

Chapter 17 STL과 객체 지향 프로그래밍과의 결합
17.1 상속과 가상 함수의 사용
17.2 컨테이너 인스턴스에서의 "코드 비대화" 방지

이었던 것으로 기억합니다.

대부분의 code 는

Appendix C 예제에서 사용했던 STL include 파일
C.1 예제 17.1에서 사용한 파일

에 있습니다.

그림문자는 Accelerated C++ 에서도 나오는데 그 시작은 Bjarne Stroustrup 의 The C++ Programming Language 였다고 합니다.(읽어보지는 못했습니다만...)

Accelerated C++ 는 개념만 빌려왔지만 STL Tutorial & Reference Guide 2nd Edition 은 source 역시 가져온 것 같습니다.

akbar의 이미지

CN wrote:
좋은 운영체제들은 프로그램이 종료될때 해제를 해주는 군요.

그렇다고 해서 프로그램이 처리못한 일을 운영체제가 처리하게 하는 일은 바보같은 일인 것 같습니다. cjh님 말처럼 차라리 스크립트 언어를 사용하는게 낫겠네요.

프로그램이 처리못한 일을 운영체제가 처리하는 것이 관점에 따라서는 바보같을 수도 있지만 그렇지 않은 것이
예를 들어 10 메가 바이트 의 메모리를 특정프로그램이 쓰고서 해제를 하지 않고 종료했다고 했을 때 운영체제가 회수해 주지 않으면
재부팅하지 않는 이상 그 10 메가 바이트의 메모리는 결코 쓸 수가 없습니다.
그러니 좀 현명한 것이라고 해야 할 것입니다.

CN wrote:

그런데 akbar님의 이야기는 현재 사용하지 않는 공간들을 운영체제가 페이징을 잘 해준다는 이야기로 받아들여도 되는 것입니까?

CN wrote:

또 무한 루프중에 계속 malloc을 실행한다는 것인가요 아니면
한번 malloc을 시켜두고 종료를 하지 않는다는 말이신가요?
장기적으로 운영체제의 페이징에 부담이 될 가능성은 없는 것인가요?

두 개의 뜻을 모두 의미합니다.
만약 무한루프 중에 계속 malloc을 실행시키면
운영체제가 바보같을 경우(또는 메모리 해제를 담당하지 않을 경우)
그 무한루프가 있는 프로그램에서 메모리를 다 소비할 것이기 때문에
다른 프로그램은 힙을 쓸 수 없어야 정상이고
그 프로그램을 (메모리 해제없이) 강제로 종료하고 나서도
다른 프로그램은 역시 힙을 쓸 수 없어야 정상입니다.
즉 멈춰서거나 다운이 되야 정상입니다.
실제는 그렇지 않죠

장기적으로는 운영체제의 페이징에 당연히 부담이 되겠지만
여기서는 짧고 단순한 프로그램을 얘기하고 있습니다.

역시 운영체제는 바보는 아닌 것 같습니다.

죠커의 이미지

akbar wrote:
CN wrote:
좋은 운영체제들은 프로그램이 종료될때 해제를 해주는 군요.

그렇다고 해서 프로그램이 처리못한 일을 운영체제가 처리하게 하는 일은 바보같은 일인 것 같습니다. cjh님 말처럼 차라리 스크립트 언어를 사용하는게 낫겠네요.

프로그램이 처리못한 일을 운영체제가 처리하는 것이 관점에 따라서는 바보같을 수도 있지만 그렇지 않은 것이
예를 들어 10 메가 바이트 의 메모리를 특정프로그램이 쓰고서 해제를 하지 않고 종료했다고 했을 때 운영체제가 회수해 주지 않으면
재부팅하지 않는 이상 그 10 메가 바이트의 메모리는 결코 쓸 수가 없습니다.
그러니 좀 현명한 것이라고 해야 할 것입니다.

제가 말을 정확하게 적지 못했네요.

그렇다고 해서 프로그램이 처리못한 일을 운영체제가 처리하게 하는 프로그래머는 바보같다고 생각합니다.

lkjt의 이미지

운영체제가 자동으로 안죽여주나요?

M$윈도우즈는 자동으로 죽여주는걸로 아는데...

리눅스는 안그런가요?

alwaysN00b의 이미지

*질문자가 아는 정도라 가정하고 설명하겠습니다. 중수이상 분들은 이해를...

1.함수를 호출할때 함수내의 변수는 스택에 있습니다.(스택구조를아셔야죠)
2.malloc함수나 new 연산자로 메모리를 할당해주면 힙부분에 할당이 됩니다.
= 힙은 해제 되지 않습니다.

질문하신분의 코드가 틀린건 아니지만 '나쁜습관' 이죠.(이유는 리플이 많이 올라와있으니 참고하시고요)

OS 가 할당되었던 메모리를 반환하지만 저렇게 코딩하다 보면 나중에 큰 프로그램이나 데몬을 작성할땐 마치 잘돌아가다 이유없이 죽는것 처럼 보입니다.

질문하신분이 원하시는 코드는 이렇게 하는게 좋을것 같네요.(물론 다른방법도 있습니다.)


#include <stdio.h> 
#include <string.h> 
#include <stdclib.h> 

char *re_str(char *ptr); 

int main() { 
   char *p="We are the world !!!";  
   char *rev;

   rev = re_str(p);
   printf("%s\n",rev); 

   free(rev);
   return 0; 
} 

char *re_str(char *ptr) { 
   char *rev; 
   int i,j; 
    
   i=strlen(ptr)-1; 
   j=0; 

   rev=(char *)malloc(strlen(ptr)+1); 

   for ( ; i>=0; i--) { 
      rev[j]=*(ptr+i); 
      j++; 
   } 

   rev[j+1]='\0'; 

   return rev; 
} 

언제나 시작

mastercho의 이미지

CN wrote:
좋은 운영체제들은 프로그램이 종료될때 해제를 해주는 군요.

그렇다고 해서 프로그램이 처리못한 일을 운영체제가 처리하게 하는 일은 바보같은 일인 것 같습니다. cjh님 말처럼 차라리 스크립트 언어를 사용하는게 낫겠네요.

그런데 akbar님의 이야기는 현재 사용하지 않는 공간들을 운영체제가 페이징을 잘 해준다는 이야기로 받아들여도 되는 것입니까? 또 무한 루프중에 계속 malloc을 실행한다는 것인가요 아니면 한번 malloc을 시켜두고 종료를 하지 않는다는 말이신가요? 장기적으로 운영체제의 페이징에 부담이 될 가능성은 없는 것인가요?

좋은 운영체제가 아니라 일반적인 OS면 프로세스에 힙 메모리
할당해주고 프로세스가 종료할때 거두어 드립니다

윈도우도 마찬가지입니다

메모리 누수라는건 프로세스가 동작하고 있을때나 의미가 있는겁니다

종료될때는 힙메모리에 대한 누수는 없습니다.....

CN wrote:

그렇다고 해서 프로그램이 처리못한 일을 운영체제가 처리하게 하는 프로그래머는 바보같다고 생각합니다.

잘못 생각하시네요

그 유명한 스티븐스의 유닉스 네트워크 프로그래밍 1권 책을 봐도
소켓을 닫아주지 않고 프로세스를 종료합니다

왜냐면 프로세스가 소켓의 리소스를 추적하고 있기때문에
프로세스가 종료시 자동으로 닫아주기 주므로
소켓을 직접 닫을 필요가 없다고 설명해 줍니다

아마 서버에서 클라이언트를 받을때 fork방법을 사용하면서
그러한 이야기를 한것으로 알고 있습니다

따라서 프로세스가 자동으로 해주는 일을 알고 있다면
바보 같은 일이 아니죠 , 오히려 현명하다고 봐야 할거 같습니다

오히려 그런한 모든것을 알고 프로그래밍 할수 있는 능력이 그루와 일반 프로그래머의 차이라고도 볼수 있을지 모르겠습니다

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

맹고이의 이미지

지금 하는 얘기는 당연히 금방 종료하는 프로그램을 말하는 거겠죠...?

아무튼, 저는 이 얘기가 마치...

어떤 어린이가 "엄마가 방 청소 해주니까 청소 안해도 되요."라고 말하는 것으로 들립니다.

뭐... 자기가 청소 안하니까 현명하다고 할 수는 있겠죠. :o

p.s. 제 생각엔 이것도 코딩 스타일이라고 생각합니다.

cdpark의 이미지

그리고 중요한 버그 하나. malloc 시에 strlen()이 아닌, strlen()+1 길이만큼 할당받아야 합니다!!

chunsj의 이미지

Windows 95/98/ME does not do this well. Also, NT has fragmentation
problem. So in Windows, you'd better clean up resources before
program exits.

mastercho wrote:
CN wrote:
좋은 운영체제들은 프로그램이 종료될때 해제를 해주는 군요.

그렇다고 해서 프로그램이 처리못한 일을 운영체제가 처리하게 하는 일은 바보같은 일인 것 같습니다. cjh님 말처럼 차라리 스크립트 언어를 사용하는게 낫겠네요.

그런데 akbar님의 이야기는 현재 사용하지 않는 공간들을 운영체제가 페이징을 잘 해준다는 이야기로 받아들여도 되는 것입니까? 또 무한 루프중에 계속 malloc을 실행한다는 것인가요 아니면 한번 malloc을 시켜두고 종료를 하지 않는다는 말이신가요? 장기적으로 운영체제의 페이징에 부담이 될 가능성은 없는 것인가요?

좋은 운영체제가 아니라 일반적인 OS면 프로세스에 힙 메모리
할당해주고 프로세스가 종료할때 거두어 드립니다

윈도우도 마찬가지입니다

메모리 누수라는건 프로세스가 동작하고 있을때나 의미가 있는겁니다

종료될때는 힙메모리에 대한 누수는 없습니다.....

CN wrote:

그렇다고 해서 프로그램이 처리못한 일을 운영체제가 처리하게 하는 프로그래머는 바보같다고 생각합니다.

잘못 생각하시네요

그 유명한 스티븐스의 유닉스 네트워크 프로그래밍 1권 책을 봐도
소켓을 닫아주지 않고 프로세스를 종료합니다

왜냐면 프로세스가 소켓의 리소스를 추적하고 있기때문에
프로세스가 종료시 자동으로 닫아주기 주므로
소켓을 직접 닫을 필요가 없다고 설명해 줍니다

아마 서버에서 클라이언트를 받을때 fork방법을 사용하면서
그러한 이야기를 한것으로 알고 있습니다

따라서 프로세스가 자동으로 해주는 일을 알고 있다면
바보 같은 일이 아니죠 , 오히려 현명하다고 봐야 할거 같습니다

오히려 그런한 모든것을 알고 프로그래밍 할수 있는 능력이 그루와 일반 프로그래머의 차이라고도 볼수 있을지 모르겠습니다

akbar의 이미지

chunsj wrote:
Windows 95/98/ME does not do this well. Also, NT has fragmentation
problem. So in Windows, you'd better clean up resources before
program exits.

If so, Windows 95/98/ME/NT is more 바보 than Linux

Testors의 이미지

chunsj wrote:
Windows 95/98/ME does not do this well. Also, NT has fragmentation
problem. So in Windows, you'd better clean up resources before
program exits.

출처는요?

mastercho의 이미지

chunsj wrote:
Windows 95/98/ME does not do this well. Also, NT has fragmentation
problem. So in Windows, you'd better clean up resources before
program exits.

참..... 저도 출처가 참 궁금하네요

제프리 리처 책을 보셨습니까?

윈도우가 heap 메모리를 어떻게 할당하는지 안다면 저런 이야기는 안하실거 같은데요?

new와 delete ,malloc , free가 사용하는 heap은 프로세스가 생성할때 운영체제가 자동으로 제공해주는 default heap 입니다

default heap크기는 컴파일할때 조절할수도 있지만 기본적으로 1메가를 부여 받고요

프로세스가 종료하면 1메가 default heap 자체 전체를 회수하게 되는겁니다

default heap의1메가 내에 500k썼던 1k썼던 프로세스에 할당된

default heap 전체를 회수하는데 ...... 회수를 제대로 못한다니요?

무슨이야기 인지 모르겠습니다

그 아무리 후진 윈도우 95조차도 default heap를 회수 못할 이유는 전혀 없는겁니다

그리고 열려진 헨들은 프로세스가 다 명단에 올려놓고 감시합니다
API 정복에서도 잘 나온내용이지요

다만 열려진 헨들중 프로세스가 종료해도 완전히 닫히지 않는
헨들도 있습니다 , 공유 되는 메모리에 관한 헨들일수도 있고
여러가지 이유가 있는데 , 그건 리눅스나 유닉스도 마찬가지입니다

이렇기 때문에 헨들을 닫는게 유용할수 있는것이지 , 윈도우가 멍청해서
리소스를 제대로 관리 하지 않는다는 말은 이해가 가지 않습니다

도데체 어디서 나온 이야기 인지 궁금하군요

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

code555의 이미지

프로그램이 종료할때는 OS가 자동으로 그동안 사용하던 메모리를 해재해 주는건 맞습니다.
하지만 윗글중에 malloc 을 무한 루프돌렸을때 os가 자동으로 메모리해재에 관여한다고 쓰신 글은 먼가 잘못 이해한 것이 아닌가 합니다.
예를 들어 10Mbyte를 100회 malloc했을때 문제가없는듯이 보이는건
단지 virtual memory heap만이 증가 했기 때문이고 물리메모리는 할당되지않죠. 하지만 malloc 한후에 거기에 데이터를 0xff등으로 초기화를 해주면 물리메모리가 할당되면서 실제 os의 사용가능한 메모리 량이 줄어들게 됩니다.
실행 시간이 짧은 프로그램은 해제 안하더라도 상관없지만 오랜 수행 예상이 되는 프로그램은 꼭 해제해줘야합니다.
이런 버그가 가장 잡기 힘듭니다.

아니면 제가 잘못 알고있었나요?
많은분들의 한말씀 부탁드립니다.

asiawide의 이미지

몇년전에 논문 프로그램 때문에 모대학 교수가 박사과정에서 작성했던 프로그램을 가져다가 쓴적이 있었습니다. 인터페이스를 파악해서 제 프로그램에 가져다가 썼는데 계속 에러가 나는 것이었습니다. 자세히 보니 free 가 하나도 없더군요. 교과서에 실릴 정도로 유명한 알고리즘을 구현한 코드였지만 한번만 돌아가게 설계되었는지라 free 가 없었습니다. -_-; 그러나 제 프로그램은 그 프로그램을 여러번 호출하기 때문에 문제가 생긴것이죠.

단적인 예로 포토샵 같은 크기가 큰 데이터를 다루는 프로그램에서 free 를 안하고 큰 파일 몇번 열고 닫고 하면 심각한 문제가 생기겠지요..

liongo의 이미지

Quote:

그렇다고 해서 프로그램이 처리못한 일을 운영체제가 처리하게 하는 프로그래머는 바보같다고 생각합니다.

지나가다 읽었지만 너무 한쪽이 치우치신 생각이신것 같습니다..

어떠한 이유나 근거로 바보같다고 생각하시는지는 모르겠지만..

위에 다른님들 말씀처럼 저도 코딩스타일이라고 생각합니다...

다른 초고수님들이 제작하신 apache, mysql 과같은 프로그램들이..

종료시키면 현재 리소스를 cleanup하고 죽는지 궁금하단 생각이들었습니다..

좀 콕 찍어서 바보라고 치부하기엔.. 좀 스케일이 큰 안건이 아닌가싶습니다..

메모리만 처리해야하나요? fork Thread모두 청소해주고 죽어야지요 ㅡㅡa?

결론은.. 알고 한다 모르고한다.. 차이 코딩스타일의 차이이겠지요..

p.s 서버 프로그래밍만 주로하는 관계로 특별히 해제후 종료의 필요성을
느끼지 못했습니다. 지나가던길의 봤는데.. 가슴이 뜨끔하군요 ㅡㅡa

' 형식이 내용을 규정한다. '

moonzoo의 이미지

오랜 시간동안 , 자주 malloc이 일어나는 프로그램이 경우

필요할때 malloc하고 "사용이 끝났으면", free해주는 것은

당연합니다.

다만 프로그램 종료직전에 free를 해주는 것은 큰 의미가 없다고

생각합니다.

종료한 프로그램이 사용한 메모리는 당연 반환될테니까요.

그것은 좋은 운영체제냐 아니냐의 문제가 아니라.

운영체제라면.. 당연히 해야할 작업이죠.

Testors의 이미지

liongo wrote:

지나가다 읽었지만 너무 한쪽이 치우치신 생각이신것 같습니다..

어떠한 이유나 근거로 바보같다고 생각하시는지는 모르겠지만..

위에 다른님들 말씀처럼 저도 코딩스타일이라고 생각합니다...

코딩 스타일일 수는 있겠지만 좋지 않은 스타일입니다.

물론 해당 코드가 어플리케이션 단위에서 동작하는 것이라면 OS 가 알아서 정리해 주겠지만,

나중에 리팩토링을 해서 그것의 성격이 바뀌었다고 생각해 보십시오.

'모든 리소스는 할당과 해제가 pair 로 분명히 짝지어져 있다' 라는 일관성이 없이는

나중에 코드를 정리하고 재배치 할 일이 생길때

'어떤 놈이 free() 를 하는지 안하는지' 트래킹도 힘들어지고 앗차하는 순간 실수 하기 쉽습니다.

지나치게 엄격해 보이는 코딩 스타일은 대개가 선배들이 실패를 발판삼아 뼈에 새겨놓은 것들이 많습니다.

'Code Complete' 나 'Writing Solid Code' 같은 책을 읽어보시길 권합니다.

참고로 'Unix Network Programming' 같은 책들의 예제가 해제를 안하는 이유는

그 코드의 목적이 '구현' 이 아니라 '설명' 이기 때문입니다.

필드에서 입문책의 예제와 같은 코드를 작성해서는 안되겠지요.

liongo wrote:

좀 콕 찍어서 바보라고 치부하기엔.. 좀 스케일이 큰 안건이 아닌가싶습니다..

메모리만 처리해야하나요? fork Thread모두 청소해주고 죽어야지요 ㅡㅡa?

물론입니다. fork() 야 관리를 해야하는 자식 process가 아닌 이상 메모리가 달라지니 무관하지만 thread 는 청소해 주어야 합니다.

thread 청소를 안해줬는데 프로그램이 정상종료 한다면 운이 좋은 거겠지요.

liongo의 이미지

흠흠. 리팩토링 과 코드 정리 재배치 트래킹..

이단어를 포함시키면 이야기가 틀려지겠지요. 저도 책을 보면 요즘..

재생산성과 버그를 유발시키는 코드를 사전에 억제하는 코딩스타일의

과 설명이 적혀있더군요.. 물론 이점에대해서 전혀 부정하지는 않습니다..

단지.. 개발자가 코딩하다보면 언제나 이점을 지키지는 않는다고 봅니다..

물론 현실적인 측면이겠지요.. 물론 버그를 일으키거나 하드코딩은 아니

합니다 저도 하지만 융통성있게 사는편이라 ㅡㅡa.. 매번 리소스해제에

대해서는 융통성있게 하는편입니다.. :) 이만줄이죠 괜히 길어지네..

저도 리팩토링 과 코드 정리 재배치 트래킹.. 인정하겠습니다.. 뭐 저이야기를

붙이고 공부하는 사람으로써 제가 무어라고 반박을 한다면

진짜.. 바보가 될꺼같아서 ^^

하지만 바보라고 지적하신분은 예제하나짤때도.
메모리해제를 OS에다 맞기신적 없으신지..

p.s 테스토스님 이 붙인 용어로 피할길이 없네요 왠지 나쁜놈된거같은..
근데 혹시 테스토스님 금공의 테스토스님 아녜용?

' 형식이 내용을 규정한다. '

pynoos의 이미지

저와 같이 일하는 팀에서 malloc을 한다음 해제를 안하는 생각을 가진 사람이 있다면
저는 그사람과 같이 일하고 싶은 생각이 들지 않을 것입니다.

이 문제는 "{" 를 어디에 두느냐와는 사뭇다른 코딩스타일 얘기입니다.

교과서, 학교 프로젝트도 아니고, 팀플레이를 해야하는 상황이라면, 구루만 혹은 자기가 코딩할 때만 알고 쓰는 것들은 최대한 배제해야합니다.

그사람이 아무리 뛰어나도 팀플레이해야하는 상황에서는 다른 사람과 co-work할 수 있느냐가 가장중요합니다.

mach의 이미지

pynoos wrote:
저와 같이 일하는 팀에서 malloc을 한다음 해제를 안하는 생각을 가진 사람이 있다면
저는 그사람과 같이 일하고 싶은 생각이 들지 않을 것입니다.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

Testors의 이미지

liongo wrote:
단지.. 개발자가 코딩하다보면 언제나 이점을 지키지는 않는다고 봅니다..
물론 현실적인 측면이겠지요.. 물론 버그를 일으키거나 하드코딩은 아니
합니다 저도 하지만 융통성있게 사는편이라 ㅡㅡa.. 매번 리소스해제에
대해서는 융통성있게 하는편입니다.. :) 이만줄이죠 괜히 길어지네..
.
.
하지만 바보라고 지적하신분은 예제하나짤때도.
메모리해제를 OS에다 맞기신적 없으신지..

liongo 님을 타박하는건 아니고,

단지 제가 해왔던 고민들을 적으면 도움이 되지 않을까 해서 긴 글을 적습니다.

저도 한때 liongo 과 같은 생각을 한 적이 있었습니다.

'현실' 을 인정하자는 것이었지요.

그렇게 프로그래머로서 오랜 시간을 지낸 뒤에 제 자신의 결과물을 뒤돌아 보았습니다.

결과는 제가 보기에도 부끄러웠습니다.

코드들은 지저분했고, 거기에는 또 이유가 주렁주렁 달려 있었습니다.

"이거 만들때는 시간이 부족했어."

"처음부터 계획이 무리였다구."

"이건 예제일 뿐이야" 등등.. 어쩔수 없었다는 이유들.

많은 프로그래머들이 쉽게 하는 말들입니다.

하지만 자존심은 있어서 제가 마음만 먹으면 그걸 제대로 할 수 있는 능력은 있다고 생각했었습니다.

그런데..

제가 보았던 많은 구루들은 단지 "만들때 운좋게 여유가 많이 주어졌던 사람들" 이었겠는가.. 하는데까지 생각이 미치더군요. 절대 그렇지 않겠지요.

결국 프로그래머는 자신이 뱉어내는 코드에 대해 모든것을 책임져야 한다는 것을 알았습니다.

그 후로 한번 쓰이고 말 예제 하나를 만들더라도 최선을 다하기 시작했습니다.

뭔가 도저히 사정이 안되어서 좋지않은 코드가 나올것 같다면.. 개발자가 해야할 일은 어떻게든 돌아가도록 코딩을 하는게 아니라 일단 코딩을 중단하고 바로 그 문제가 되는 환경을 개선하는 일이라고 생각합니다.

어려워 보이지만 해보니 의외로 쉽더군요.

도저히 말이 통할것 같지 않던 관리자들도 "이만큼의 시간이 주어지지 않으면 아예 결과를 내지 않겠다" 라고 땡깡을 부리니 어떻게든 시간을 만들어 주었습니다.

그 다음 일은 그렇게 주어진 조건 하에서 제가 할수 있는 최선을 다하는 것이었습니다.

그리고 저는 여유만 주어지면 괜찮은 코드를 만들 수 있을거라고 생각했던것이 큰 착각임을 알았었습니다.

얼마나 많은 자기반성과 공부가 필요한지...

저는 핑계와 합리화에 가려 제자신을 보지 못했던 것입니다.

지금도 제대로 아는것은 없습니다.

단지 다행인 점이라면 "무엇을 해야 하는지" 는 이제 보인다는 것이죠.

그리고 계속 노력 중입니다.

liongo wrote:

p.s 테스토스님 이 붙인 용어로 피할길이 없네요 왠지 나쁜놈된거같은..
근데 혹시 테스토스님 금공의 테스토스님 아녜용?

맞습니다. : D

chunsj의 이미지

Testors wrote:
chunsj wrote:
Windows 95/98/ME does not do this well. Also, NT has fragmentation
problem. So in Windows, you'd better clean up resources before
program exits.

출처는요?

이전에 항공기 설계를 위한 시스템을 만들때인데 시스템 설계 과정에서 최적화
를 위해서 많은 메모리가 필요했습니다. 그런데 동일한 최적화 코드가
윈도에서는 10회정도 이상 실행이 되면(연속해서 해도 되고 또는 매회
프로그램을 새로 시작하더라도) 무진장 느려지거나 연속된 블럭을 할당 할
수 없다는 이상한(?) 에러를 내면서 실행을 거부하더군요. 그래서 윈도용은
좀 느리더라도 다른식으로 동작을 하게 프로그램을 수정했던 적이 있습니다.
이 문제 때문에 MS에 지원을(미국 MS입니다.) 요청했었는데(물론 e-Mail로)
이에 대한 답변이 많은 메모리의 할당을 자주 반복할 경우 메모리 단편화
현상이 있을 수 있다고 답변이 오더군요. 95, 98은 원래 부터 쓰레기다라고
생각을 했었기 때문에 뭐 별로 놀랍지 않았지만 (그리고 참가한 엔지니어들도
이미 알고 있었고) NT도 그렇다는 것에서는 좀 놀랐었습니다. 그 때 자세히
알아보지는 않았었는데, Unix/Linux등이 사용하는 메모리 관리와 NT의
것이 다르다고 들었습니다. 전자가 우리의 경우에 대해서는 훨씬 Robust하다
고 하더군요.

직접 해 보시는 것이 가장 좋은 방법이라고 생각됩니다.

chunsj의 이미지

위에 제가 쓴 글과 같이 저도 겪어보고 답변을 받아서 알게된 사실입니다.
그리고 책에 그렇게 쓰여있다고 그게 완벽하게 동작한다고 생각하시나요?
특히 소스도 볼 수 없는데도? 그렇게 완벽하면 왜 다운 잘되는 걸로 유명
하겠습니까?

그리고 당연히 Linux/Unix도 비슷한 문제가 있을 수 있습니다. 단지 덜
발생을 하더라 라는 것일 뿐이죠. 그리고 저는 윈도가 멍청하다고 한 적은
없습니다. 저런 문제가 있더라 하는 것이지요.

님은 윈도와 C++에 대해서 너무 민감하게 반응을 하시는 것 같습니다. :-)

mastercho wrote:
chunsj wrote:
Windows 95/98/ME does not do this well. Also, NT has fragmentation
problem. So in Windows, you'd better clean up resources before
program exits.

참..... 저도 출처가 참 궁금하네요

제프리 리처 책을 보셨습니까?

윈도우가 heap 메모리를 어떻게 할당하는지 안다면 저런 이야기는 안하실거 같은데요?

new와 delete ,malloc , free가 사용하는 heap은 프로세스가 생성할때 운영체제가 자동으로 제공해주는 default heap 입니다

default heap크기는 컴파일할때 조절할수도 있지만 기본적으로 1메가를 부여 받고요

프로세스가 종료하면 1메가 default heap 자체 전체를 회수하게 되는겁니다

default heap의1메가 내에 500k썼던 1k썼던 프로세스에 할당된

default heap 전체를 회수하는데 ...... 회수를 제대로 못한다니요?

무슨이야기 인지 모르겠습니다

그 아무리 후진 윈도우 95조차도 default heap를 회수 못할 이유는 전혀 없는겁니다

그리고 열려진 헨들은 프로세스가 다 명단에 올려놓고 감시합니다
API 정복에서도 잘 나온내용이지요

다만 열려진 헨들중 프로세스가 종료해도 완전히 닫히지 않는
헨들도 있습니다 , 공유 되는 메모리에 관한 헨들일수도 있고
여러가지 이유가 있는데 , 그건 리눅스나 유닉스도 마찬가지입니다

이렇기 때문에 헨들을 닫는게 유용할수 있는것이지 , 윈도우가 멍청해서
리소스를 제대로 관리 하지 않는다는 말은 이해가 가지 않습니다

도데체 어디서 나온 이야기 인지 궁금하군요

Testors의 이미지

chunsj wrote:

이전에 항공기 설계를 위한 시스템을 만들때인데 시스템 설계 과정에서 최적화
를 위해서 많은 메모리가 필요했습니다. 그런데 동일한 최적화 코드가
윈도에서는 10회정도 이상 실행이 되면(연속해서 해도 되고 또는 매회
프로그램을 새로 시작하더라도) 무진장 느려지거나 연속된 블럭을 할당 할
수 없다는 이상한(?) 에러를 내면서 실행을 거부하더군요. 그래서 윈도용은
좀 느리더라도 다른식으로 동작을 하게 프로그램을 수정했던 적이 있습니다.
이 문제 때문에 MS에 지원을(미국 MS입니다.) 요청했었는데(물론 e-Mail로)
이에 대한 답변이 많은 메모리의 할당을 자주 반복할 경우 메모리 단편화
현상이 있을 수 있다고 답변이 오더군요. 95, 98은 원래 부터 쓰레기다라고
생각을 했었기 때문에 뭐 별로 놀랍지 않았지만 (그리고 참가한 엔지니어들도
이미 알고 있었고) NT도 그렇다는 것에서는 좀 놀랐었습니다. 그 때 자세히
알아보지는 않았었는데, Unix/Linux등이 사용하는 메모리 관리와 NT의
것이 다르다고 들었습니다. 전자가 우리의 경우에 대해서는 훨씬 Robust하다
고 하더군요.

이 쓰레드의 주제는 "프로세스 종료시 OS 의 리소스 회수 처리" 입니다.

제가 보기에는 제시하신 예는 "Heap 단편화 문제" 로 보입니다.

참고로 작업하신게 아주 예전의 일이라면,

그것은 OS 의 문제가 아니라 CRT 의 문제일 수도 있습니다.

최근의 malloc() 은 HeapAlloc() 과 1:1 대응입니다만, 이전의 CRT 에서는 그렇지 않았습니다.

그리고 95/98 이 쓰래기 라기 보다는

16-bit 와의 호환성을 포기하지 않기 위해 trade-off 했다고 보는편이 정확할 것입니다.

개인적으로는 그정도면 꽤나 훌륭하다고 생각합니다.

chunsj wrote:
직접 해 보시는 것이 가장 좋은 방법이라고 생각됩니다.

수년째 Win32 환경에서 작업해오고 있자만 아직 겪어본적이 없군요. :wink:

덧. OS 우열 논쟁으로 번지지 않았으면 합니다.

덧2. 여전히 해당 글의 출처가 궁금합니다. :)

mastercho의 이미지

chunsj wrote:
위에 제가 쓴 글과 같이 저도 겪어보고 답변을 받아서 알게된 사실입니다.
그리고 책에 그렇게 쓰여있다고 그게 완벽하게 동작한다고 생각하시나요?
특히 소스도 볼 수 없는데도? 그렇게 완벽하면 왜 다운 잘되는 걸로 유명
하겠습니까?

그리고 당연히 Linux/Unix도 비슷한 문제가 있을 수 있습니다. 단지 덜
발생을 하더라 라는 것일 뿐이죠. 그리고 저는 윈도가 멍청하다고 한 적은
없습니다. 저런 문제가 있더라 하는 것이지요.

님은 윈도와 C++에 대해서 너무 민감하게 반응을 하시는 것 같습니다. :-)


글세요

다운이 되는 원인은 여러가지 이유가 있을수 있습니다

chuns님이 주장하시는것은 단지 ... 추측일뿐이라는 생각이 듭니다

[ 특히 98이하에서는 잘못된 OS 메모리 접근에 예외를 내지 않는 경우가
많습니다 , 이것이 98의 큰 약점이죠
단 프로세스간 메모리 접근은 예외를 냅니다 , 다운이 잦은 이유는
아마도 이러한 메모리 접근에 관한 부분일 확률이 매우 큽니다.
윈도우를 공부하셨다면 98이하의 약점이 뭔지 잘 아셨을텐데요
98이하는 다운 되는 이유가 , 프로세스가 리소스를 해제 못하는 이유라기보단 , 근본적인 다른 문제가 있는겁니다]

그리고 전 완벽하다고 한적은 없습니다

윈도우의 완벽히 공부했던 사람의 책 내용을 살펴보고 일반적으로 그렇게 돌아간다는 이야기를 한것뿐이죠

사실 printf에도 버그가 있을지 누가 압니까? 그런식으로 완벽을 주장하시면
버그 없는 프로그램은 존재하지 않습니다 ....

그리고 제가 했던
멍청하다는 말은 chuns님말을 듣고 밑에 분이, 영어로 "그럼 윈도우가 리눅스보다 멍청하다 "고 하셔서 한말입니다 오해는 없으시길를......

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

Testors의 이미지

mastercho wrote:
사실 printf에도 버그가 있을지 누가 압니까?

예전 버젼의 libc 에는 printf 가 1024 byte 이상의 문자열을 받지 못하는 버그가 있었습니다.

(받으면 세그먼트 폴트)

아마 96년도 쯤의 일로 기억이 되는군요 :)

mastercho의 이미지

chunsj wrote:
Testors wrote:
chunsj wrote:
Windows 95/98/ME does not do this well. Also, NT has fragmentation
problem. So in Windows, you'd better clean up resources before
program exits.

출처는요?

이전에 항공기 설계를 위한 시스템을 만들때인데 시스템 설계 과정에서 최적화
를 위해서 많은 메모리가 필요했습니다. 그런데 동일한 최적화 코드가
윈도에서는 10회정도 이상 실행이 되면(연속해서 해도 되고 또는 매회
프로그램을 새로 시작하더라도) 무진장 느려지거나 연속된 블럭을 할당 할
수 없다는 이상한(?) 에러를 내면서 실행을 거부하더군요. 그래서 윈도용은
좀 느리더라도 다른식으로 동작을 하게 프로그램을 수정했던 적이 있습니다.
이 문제 때문에 MS에 지원을(미국 MS입니다.) 요청했었는데(물론 e-Mail로)
이에 대한 답변이 많은 메모리의 할당을 자주 반복할 경우 메모리 단편화
현상이 있을 수 있다고 답변이 오더군요. 95, 98은 원래 부터 쓰레기다라고
생각을 했었기 때문에 뭐 별로 놀랍지 않았지만 (그리고 참가한 엔지니어들도
이미 알고 있었고) NT도 그렇다는 것에서는 좀 놀랐었습니다. 그 때 자세히
알아보지는 않았었는데, Unix/Linux등이 사용하는 메모리 관리와 NT의
것이 다르다고 들었습니다. 전자가 우리의 경우에 대해서는 훨씬 Robust하다
고 하더군요.

직접 해 보시는 것이 가장 좋은 방법이라고 생각됩니다.

ㅎㅎ 그리고 .... 단편화하고 리소스 해제 하는거하고 무슨 연관이 있는지
모르겠네요

유닉스의 내부 책를 보면 메모리 할당 해제시
단편화는 리눅스나 유닉스도 똑같이 발생할수 있으며

모든 운영체제에서 이것을 특정 알고리즘으로 해결합니다

따라서 단편화에 관한 속도 차이는 메모리 관리를 어떤 알고리즘으로 하느냐에 따라 유닉스와 리눅스끼리도.... 차이가 많이 나게 됩니다

그리고 만약 속도가 유닉스가 더 빠르다면 , 속도를 위해 메모리를 더 희생했을 확률도 크고요

Buddy 알고리즘을 쓴다고 책에서 보았지만 , 그 실제 구현은 OS 벤더 마다 다를것입니다

[참고로 윈도우가 유닉스보다 오히려 늦게 나왔기때문에 더 좋은 알고리즘으로
구현했을수도 있습니다 , 동시대 윈도우와 유닉스를 비교했을 당시요,물론 추측이니다 :wink: ]

많은 알고리즘의 장단점이 있듯이, 장점이 있으면 단점이 있는법입니다

단지 MS에서 malloc free 많이 하면 단편화가 발생할수 있다는 말에...
윈도우가 더 후지다는 생각을 했다면.... OS책 한번 다시 보셔야 할거 같습니다

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

jqka1의 이미지

리팩토링 과 코드 정리 재배치 트래킹.. 을 위해서라면 많은것들을 생각해야겠지요.. 이 코드가 어디에 사용될것인지 를 모두 생각한뒤에.. 코딩해야 한다는건데.. 불가능 하지 않나요? 새로운 개념이 나오면요?
라이브러리 함수들이 좋은 예일텐데..
아무리 좋은 라이브러리 함수라 할지라도 새로운 문제점들 때문에 계속 보완되지않나요? 예를 들어 thread safe에 관계된 것들.. 그 외에도 많이 있겠죠..

아무리 잘되어있는 코드라도 전체적인 검토후에 사용해야 된다고 생각합니다..
현재 구조에 필요없는것들은 빼고 필요한건 덧붙이고.. 이작업은 반드시 해야하는거구요.. 굳이 필요없는 코드가 빠진다면 최소한 실행화일크기는 줄어들겠죠..

mastercho의 이미지

참 지금 책이 없어 확인은 못해보지만

제 기억으로는 리눅스나 유닉스는 힙메모리를 링크드리스트로 관리를 합니다

그리고 2배 단위로 메모리를 할당하기때문에 치명적인 내부 단편화를 유발할수 있습니다

예를 들면 1메가 할당에 1바이트라도있으면 1메가 할당을 위해
2메가를 할당해야합니다

그리고 링크드 리스트의 구조상 빠른 할당과 해제가 가능하지만

그 할당과 해제 시간의 간격이 커 .... 링크드리스트가 길어질수록
속도는 무지막지 저하 될것입니다

한마디로 모든 구조는 장단점이있습니다

윈도우의 힙 구조는 외부 단편화때문에 골머리를 썩는거 같더군요

그래서 디폴트 힙 말고도 다른 힙을 두어서 관리할수 있는 기법도 있습니다

승자는 자기보다 우월한 사람을 보면 존경심을 갖고 그로부터 배울 점을 찾지만 패자는 자기보다 우월한 사람을 만나면 질투심을 갖고 어디 구멍난 곳이 없는지 찾는다.
- 하비스

advanced의 이미지

리눅스/glibc 에서의 malloc 구현에 대한 짧막한 글입니다

우연찮게 보았는데 마침 이런 스레드가 있어서

참고 하시라고 올립니다

http://gee.cs.oswego.edu/dl/html/malloc.html

mach의 이미지

메모리 free문제가 운영체제의 능력(?)으로 비약되고 있군요. :shock:

다시 질문하신분의 주제로 돌아가서
"free()하도록 하세요."라고 권고합니다.

메모리관리를 운영체제에 맡기는 패턴이 좋다고 생각하거나, 익숙하다면 개발툴을
C에서 메모리관리 필요없는 Java (JVM)이나, 아니면, 어떤 스크립트언어로 전향하는게 맞다고 생각하는 바입니다.

------------------ P.S. --------------
지식은 오픈해서 검증받아야 산지식이된다고 동네 아저씨가 그러더라.

지나가다..의 이미지

지나가다 본 글인데.. free를 안해줘도 된다는 답변도 있는것에 놀라고 갑니다.

C,C++ 처럼 프로그램상의 메모리를 프로그래머가 직접관리해줘야 하는 언어에서... 할당과 해제는 기본중에 기본인데...

놀라움을 넘어 약간의 경악마저 드는군요...

함수내에서 해제되는 메모리는 지역변수뿐이죠.. static 이나 전역변수는 데이터 영역에 쓰여지기 때문에 프로그램이 종료되야

메모리가 반환되죠.. 그리고 malloc 같은 함수로 할당받은 것은 heap메모리 영역에 할당되고 프로그램이 종료되거나, 프로그래머가

해제해줘야 반환됩니다. 해제를 해주지 않으면 실행중에 필요없는 메모리 누수가 일어나는거죠..

특히 이런 할당코드가 반복적으로 실행된다면... 그 결과는...

반드시 할당한 메모리는 그 용도를 다 쓰고나서 해제해줘야 합니다.

기본중에 기본입니다.

오래된 글이지만, 이제 프로그램을 시작하시는 분들이 볼수도 있으니... 답변달고 갑니다.

익명 사용자의 이미지

특정 OS에 따라 free를 사용하지 않고 OS에 자원을 반환 할 수 있습니다.
windows의 경우 private heap을 선언하고 HeapAlloc과 HeapFree를 사용할 수 있는데
HeapFree를 사용하지 않고 private heap을 제거하는 방법도 있습니다.
그럴경우 heap은 제거되고 heap이 가지고 있던 메모리 공간은 OS에 즉각 반환되지요.

제프리 리처 책에 보면 이런 방법을 반환해제(Quick free)라 설명하고 있으며
수행 속도도 빠르고 편리하여 많은 애플리케이션에서 사용한다라고 설명되어 있습니다.
For many applications, this can be extremely convenient—and they'll run faster too.

sshtel의 이미지

지나가다 한마디 하자면,

free는 반드시 해야 합니다.

그게 C++ 언어의 본질이고 문화입니다.

Window OS에서 제공하는 그러한 함수들은 어차피 내부적으로 메모리 관리를 해주도록 편의상(?) 만든 것이고
표준도 아닐뿐더러 그것을 사용하는 사람들이 충분히 숙지하고 사용하면 편할 뿐입니다.

그러니 이 글타래 주제와는 조금 다른 것 같습니다.

익명 사용자의 이미지

더 이상 할당받은 자원이 필요없을땐 free()를 해줘야 합니다

프로그램이 종료되면 운영체제가 없어주는거 같으니 안해도 될 거 같다는 의견이 더러 보입니다만

프로그램이 종료라도 되면 다행이겠습니다만

24시간 365일 논스톱으로 돌려야 하는 서버 프로그램에서 그런 함수를 호출해서 사용하게 된다면...

아무갣355ㄱ45의 이미지

제 생각에 cpu속도와 메모리 속도는 차이가 납니다.
그리고 메모리나 하드나 저장공간으로서 할당영역이 디스크 조각 모음처럼 오래 할당해제를 자주 하다 보면
큰 공간의 메모리는 작은 공간의 메모리 사이에는 할당할 수 없습니다. 하드기스크 할당과 동일한 문제 입니다.
작은 메모리들의 반복적 할당해제와 큰 메모리들의 할당해제가 자주 반복되면 속도 문제때문에 할당을 여유로운 주소에서 하게 됩니다. 그런데 해제 시에는 비교적 늦게 그리고 링크드라 해제가 늦어지게 되는데, 해데되는 순간 순간마다 여유 공간 파악을 할 수 없기때문에 지연이 일어납니다. 프로세스를 종료하더라도 작고 큰 메모리가 많은 프로세스가 여러 멀티 태스킹을 하고있다면은
일정 횟수 후에 큰 메모리 할당이 안되서 시작하지 못하거나, 시작 후 큰메모리 할당 실패로 할당지연이 일어날때 할당된줄 짧은 시간에 생각하고 잘못된 할당주소에 젖근하여 크래쉬가 일어날 수 있습니다.

아무개요56의 이미지

프로그램 시작 시 순간 최대 동적 또는 정적 메모리양을 할당하고 시작하면 좋습니다.
이 경우 메모리는 더 쓰지만 어떤 부하도 os에 주질 않고 할당해제의 문제와 접근 속도에도 유리합니다.
그러나 메모리 부족한 하드웨어라면 동적메모리의 크기 일정화와 개수를 최대한 줄이는게 좋습니다.
수많은 다른 크기의 메모리를 빡빡하게 포인터로 관리하는 건 좋지 않죠. 오히려 정적으로 다 잡고 시작하는게 안정성이나 속도면에서 매우 유리합니다.(주소계산)
효율은 떨어지겠지만요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.