calloc, realloc, free 등의 사용법에 대한 질문

y9150의 이미지

안녕하세요. 프로그래밍을 전공으로 배운 학생은 아닌데 당장 프로그래밍을 해야하기에 이론적 바탕없이 애를 먹고 있습니다 ^^;;

아래의 코드에서 componentList라는 것을 만들었고, SearchComponent라는 함수에서 realloc하여 사용한 후 해제하려고 하는데요.

코드를 돌려 "yo"와 "gurt" 사이에서 에러 메세지가 출력되는 것을 확인했습니다.

사실 realloc 함수를 사용하면서 allocation 관련한 오류를 너무 자주 만나고 있고 이론적 지식이 없기에 애를 먹고 있습니다..

이 코드에서는 왜 오류가 나고 있는 것이고 어떻게 고치는 것이 좋을까요?

int *componentList;
componentList = (int*) calloc (1,sizeof(int));
componentList[0] = totalNodes;
int *componentSize;
componentSize = (int*) calloc (1,sizeof(int));
SearchComponent(layer, nodeNum, layerNum, componentList, componentSize, didWeCheckThisNode);
int listSize = componentSize[0];
compList = (COMPONENTS*) realloc (compList, sizeof(COMPONENTS)*(1+compListNum));
compList[compListNum].size = listSize;
compList[compListNum].element = (int*) realloc (compList[compListNum].element, sizeof(int)*listSize);
for(int elementNum = 0; elementNum < listSize; elementNum++)
	compList[compListNum].element[elementNum] = componentList[elementNum];
compListNum ++;
cout << "yo"<< endl;
free(componentList);
cout << "gurt"<< endl;
free(componentSize);
cout << "yum"<< endl;

세벌의 이미지

에러메시지는 무엇인가요?

저는

sebul@sebulnet:~$ g++ -Wall -o a a.cpp

했더니
a.cpp:2:1: error: ‘componentList’ does not name a type
 componentList = (int*) calloc (1,sizeof(int));

로 시작하는 에러가 나던데...
y9150의 이미지

malloc: *** error for object 0x7fb2c54033c0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
이라는 에러가 뜹니다.

세벌의 이미지

님께서 올린 소스 코드에서는 malloc 함수를 쓰지도 않으셨는데요?
cout 이 있는 걸 보면 c++ 같은데...
그렇다면 malloc 대신 new 를 쓰실 것을 권합니다.
https://stackoverflow.com/questions/184537/in-what-cases-do-i-use-malloc-vs-new?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

y9150의 이미지

예. calloc이나 realloc, free함수에서 오류가 나면 항상 malloc이라는 이름으로 오류가 나더군요. new나 delete를 사용할 것도 생각해본 적이 있는데 new로 선언되는 경우 배열의 크기를 사용 중에 바꿀 방법을 알지 못해 사용하지 못하고 있습니다.

세벌의 이미지

y9150의 이미지

음.. 이미 검색해보고도 알 수 없어 질문 드렸던건데... 어찌되었던 도움주셔서 감사드립니다.

jick의 이미지

답은 아니지만, C++이면 그냥 vector를 사용하시는 걸 추천합니다.

malloc/free/realloc이 어떻게 돌아가는지 신경 안 써도 됩니다.

* 물론 여전히 메모리 잘못 쓰면 깨지는 거야 당연합니다만...

y9150의 이미지

역시 벡터가 답인가요... 새로운거 배우려면 밤을.. 더 많이 새야겠군요 (눈물)

karkayan의 이미지

SearchComopnent 함수 코드가 없어서 확실치 않지만,
SearchComponent에서 realloc을 하고 새롭게 allocation된게 아니라 예전 allocation된 것을 쓰고 있
는건 아닌가요?
SearchComponent에서 componentList 인자 타입이 int*&가 아니라 int*라면 realloc 후에 새 주소를 componentList로 전달하지 않아 생긴 문제 같네요.

compList[compListNum].element =
  (int*) realloc (compList[compListNum].element, sizeof(int)*listSize);

부분도 조금 이상한데 compList[compListNum]은 방금 realloc으로 새로 확장된 부분인것 같은데요. 그러면 compList[comListNum].element는 이전에 allocation된 메모리 주소가 아니니, realloc이 아니라 malloc이나 calloc을 써야 합니다.

malloc, realloc, free의 man page를 자세히 읽어보시면 도움이 될겁니다.

y9150의 이미지

int*가 아니라 int*&를 써야하는거군요! int* XXX로 쓰면 이전 함수에서의 포인터 XXX가 저장하고 있던 데이터들을 가져와 새로운 포인터로 선언해버리는건가요??

shint의 이미지

- malloc 크기만큼 메모리 할당
- realloc 할당된 메모리 크기를 변경
- calloc 크기와 갯수로 메모리 할당

- 각 함수의 인자값. 리턴값. 오류값을 확인해 보시기 바랍니다.
- printf()와 return 문으로 결과값을 출력해서. 디버깅 해보시기 바랍니다.
- 할당된 메모리는 해제 하시는것이 좋습니다.

http://codepad.org/K4UKJq4T

#include <stdio.h>
 
typedef struct DF_COMPONENTS
{
    int size;
    int* element;
}COMPONENTS;
 
COMPONENTS * compList;
 
int compListNum = 3;
int totalNodes = 3;
 
 
void SearchComponent(int layer, int nodeNum, int layerNum, int * componentList, int * componentSize, int didWeCheckThisNode)
{
    *componentSize = 3;
}
 
 
int main()
{
    int elementNum;
 
    int *componentList;
    componentList = (int*) calloc (1,sizeof(int));
    memset(componentList, 0x00, sizeof(int));
    componentList[0] = totalNodes;
 
printf("componentList size %d\n", sizeof(int));
printf("totalNodes %d\n", totalNodes);
 
    int *componentSize;
    componentSize = (int*) calloc (1,sizeof(int));
    memset(componentSize, 0x00, sizeof(int));
printf("componentSize %d\n", sizeof(int));
 
    int layer=0;
    int nodeNum=0;
    int layerNum=0;
    int didWeCheckThisNode=0;
    SearchComponent(layer, nodeNum, layerNum, componentList, componentSize, didWeCheckThisNode);
 
    int listSize = componentSize[0];
printf("listSize %d\n", listSize);
printf("compList %x\n", (unsigned int)compList);
    compList = (COMPONENTS*) realloc (compList, sizeof(COMPONENTS)*(1+compListNum));
    memset(compList, 0x00, sizeof(COMPONENTS)*(1+compListNum));
printf("compList realloc size %d\n", sizeof(COMPONENTS)*(1+compListNum));
//return 0;
 
printf("compList %x\n", (unsigned int)compList);
printf("compList+0 %x\n", (unsigned int)compList+0);
printf("compList+1 %x\n", (unsigned int)compList+1);
printf("compList+2 %x\n", (unsigned int)compList+2);
printf("compList+3 %x\n", (unsigned int)compList+3);
printf("compList+4 %x\n", (unsigned int)compList+4);
 
    compList[compListNum].size = listSize;
printf("compListNum %d\n", compListNum);
printf("compList[compListNum].size %d\n", compList[compListNum].size);
//return 0;
 
//Segmentation fault 발생
printf("compList[0].element %x\n", (unsigned int)compList[0].element);
printf("compList[1].element %x\n", (unsigned int)compList[1].element);
printf("compList[2].element %x\n", (unsigned int)compList[2].element);
 
/*
    compList[compListNum].element = (int*) realloc (compList[compListNum].element, sizeof(int)*listSize);
    memset(compList[0].element, 0x00, sizeof(int)*listSize);
    memset(compList[1].element, 0x00, sizeof(int)*listSize);
    memset(compList[2].element, 0x00, sizeof(int)*listSize);
    memset(compList[3].element, 0x00, sizeof(int)*listSize);
 
return 0;
 
    compList[compListNum].element = (int*) malloc (sizeof(int));
    compList[compListNum].element = (int*) realloc (compList[compListNum].element, sizeof(int)*listSize);
    memset(compList[0].element, 0x00, sizeof(int)*listSize);
    memset(compList[1].element, 0x00, sizeof(int)*listSize);
    memset(compList[2].element, 0x00, sizeof(int)*listSize);
    memset(compList[3].element, 0x00, sizeof(int)*listSize);
 
return 0;
*/
 
//    compList[compListNum].element = (int*) malloc (sizeof(int)*listSize);
    compList[compListNum].element = (int*) realloc (compList[compListNum].element, sizeof(int)*listSize);
 
printf("compList[compListNum].element realloc size %d\n", sizeof(int)*listSize);
//return 0;
 
 
    for(elementNum = 0; elementNum < listSize; elementNum++)
    {
	compList[compListNum].element[elementNum] = componentList[elementNum];
printf("compList[compListNum].element[elementNum] %d\n", compList[compListNum].element[elementNum]);
printf("componentList[elementNum] %d\n", componentList[elementNum]);
printf("elementNum %d\n", elementNum);
    }
 
 
    free(compList[compListNum].element);
printf("free(compList[compListNum].element)\n");
 
 
    compListNum ++;
printf("compListNum ++ %d\n", compListNum);
//return 0;
 
    cout << "yo"<< endl;
 printf("free(componentList)\n");
    free(componentList);
    cout << "gurt"<< endl;
 printf("free(componentSize)\n");
    free(componentSize);
    cout << "yum"<< endl;
}
 
//http://www.cplusplus.com/reference/cstdlib/calloc/
//https://www.ibm.com/support/knowledgecenter/ko/ssw_ibm_i_73/rtref/calloc.htm
//http://dsnight.tistory.com/51
//https://pat.im/109

//출력 결과
componentList size 4
totalNodes 3
componentSize 4
listSize 3
compList 0
compList realloc size 32
compList 9e31488
compList+0 9e31488
compList+1 9e31489
compList+2 9e3148a
compList+3 9e3148b
compList+4 9e3148c
compListNum 3
compList[compListNum].size 3
compList[0].element 0
compList[1].element 0
compList[2].element 0
compList[compListNum].element realloc size 12
compList[compListNum].element[elementNum] 3
componentList[elementNum] 3
elementNum 0
compList[compListNum].element[elementNum] 215
componentList[elementNum] 215
elementNum 1
compList[compListNum].element[elementNum] 0
componentList[elementNum] 0
elementNum 2
free(compList[compListNum].element)
compListNum ++ 4
yo
free(componentList)
gurt
free(componentSize)
yum

----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.

매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.

각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com

y9150의 이미지

사이트 즐겨찾기 추가를 잊어버려서 댓글을 이제서야 보았네요 ㅜ.ㅜ memset은 값을 초기화하려고 쓴 것으로 이해했는데 그 안에 써있는 0x00은 무슨의미인가요? 또한 return 함수는 어떤 의도로 사용되고 있는 것인가요?

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.