2012-08-13 3 views
0

나는 주요 이중 포인터를 선언하고 내가 함수에이 배열을 통과 한이libc의 감지 *** ./textfileread.exe : realloc을() : 유효하지 않은 다음 크기 : 0x08643008

char **group_name; 
group_name = realloc(NULL, 1); 
group_name[0] = realloc(NULL ,20); 

처럼 메모리를 할당 한

group_count(object, count, group_name); 

realloc을 사용합니다. 첫 번째 네 개의 재 할당이 채워질 때까지 벌금이 부과되지만, 다섯 번째 오류가 발생하면 벌금이 부과됩니다.

libc detected *** ./textfileread.exe: realloc(): invalid next size: 0x08643008 

int group_count(struct friends obj[], char cn, char **grp_nm) 
{ 
    int i=0,j=0; 
    int grp_cn=0; 
    char check=0; 
    strcpy(grp_nm[0],obj[0].group); 
    grp_cn++; 
    grp_count++; 

    for(i=1;i<cn;i++) { 
     for(j=0;j<grp_cn;j++) { 
      if(strcmp(grp_nm[j],obj[i].group)==0) 
       check=1; 
     } 
     if(check==0) { 
      grp_cn++; 
      grp_count++; 
      printf("\t%d\n",grp_cn); 
      grp_nm = realloc(grp_nm, grp_cn); //at grp_cn=5 allocation gives error 
      printf("\t%d\n",grp_nm); 
      if(grp_nm == NULL) printf("\t%d\n",grp_cn); // this 'if' didnt run, means no NULL return 
      grp_nm[grp_cn-1] = realloc(NULL ,20); 
      strcpy(grp_nm[grp_cn-1],obj[i].group); 
     } 
    check=0; 
    } 
} 

printf ("\ t % d \ n", grp_nm)의 출력; 화면에 출력 5 이후에 재 할당

2 
140783624 
3 
140783624 
4 
140783624 
5 

*** glibc detected *** ./textfileread.exe: realloc(): invalid next size: 0x099c8008  *** 
======= Backtrace: ========= 
/lib/i386-linux-gnu/libc.so.6(+0x6b961)[0x17b961] 
lib/i386-linux-gnu/libc.so.6(+0x6f1ad)[0x17f1ad] 
/lib/i386-linux-gnu/libc.so.6(realloc+0xe9)[0x180579] 
./textfileread.exe[0x804934e] 
./textfileread.exe[0x8048b42] 
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x126e37] 
./textfileread.exe[0x8048751] 
======= Memory map: ======== 
00110000-0026a000 r-xp 00000000 08:02 1570626 /lib/i386-linux-gnu/libc-2.13.so 

의 5 번 반복에 후, 아래, 그것은 4. 이후 표시된 주소가 표시되어야하지만 일부러, 왜 5에서 그 오류를 줄?

+0

오히려 printf와 사용하도록 ("% P는"grp_nm) 포인터를 표시합니다. 의미있는 형식을 사용하고 ptr-int 암시 적 캐스팅에 대한 경고를 피하며 int/pointer 크기가 다른 시스템에서 코드를 사용하는 경우 출력을 휴지통에 버리지 않습니다. – PypeBros

답변

1

초기 할당에 realloc을 사용해야하는 이유는 무엇입니까? 어쨌든

은 ...
char **group_name; 
group_name = realloc(NULL, 1); 
// group_name is now pointing to 1 byte of dynamically allocated memory 
group_name[0] = realloc(NULL ,20); 
// Whoops. Did we just write 4(or more bytes) into our 1 allocated byte? 

나는 동일한 문제가 당신의 방법 내부에 존재하는 것 같아요.

+0

realloc은 NULL과 함께 사용할 때 malloc과 다를 수 있습니다. 그냥 코드의 유사성을 kepp. –

0

할당 할 때 잘못된 크기를 사용하기 때문에 문제가 발생할 가능성이 큽니다.

char **group_name; 
group_name = realloc(NULL, 1); 

하지만 char **하지 하나의 바이트가, 그것의 하나 (당신이 32 또는 64 비트 플랫폼에서 경우에 따라) 4 개 또는 8. 당신이 재 할당 할 때 나중에

group_name = realloc(NULL, sizeof *group_name); 

그리고 : 대신 sizeof 연산자를 사용

grp_nm = realloc(grp_nm, grp_cn * sizeof *grp_nm); 
+1

아마도'realloc (NULL, sizeof * group_name);을 의미 할 것입니다. –

+0

괜찮아, 내가 시도 할 것이지만, 내가 아는 한 이미 8 비트가 1 바이트를 의미하므로 sizeof를 할 필요가 없다. 나는 sizeof가 int 나 float 타입에 필요하지만 char에는 필요하지 않은 다른 응답에서 이것을 보았다. 그러나 나는 시도 할 것이고, 결과를 게시 할 것이다. –

+0

@ JensGustedt 네, 맞습니다. 감사. –

2

문제의 핵심은 당신이 malloc을 당신의 갓과 함께 설정하는 책을 지키는 포인터를 손상하고 있다는 것입니다 할당 된 블록. "블록"을 realloc으로 되돌려 놓으면 손상된 포인터를 사용하여 메모리를 자유 영역 및 다른 유사한 활동에 다시 삽입합니다.

"5와 4가 아닌 이유는 ..."왜냐하면 realloc은 이전에 반환 된 블록 중 하나를 사용할 필요가 없었기 때문일 가능성이 큽니다 (예 : 블록이 실제로 요청한 것보다 크기 때문에 realloc은 괜찮을 것이라고 생각합니다. 일부 메모리를 다시 할당하지 않고). malloc/free는 복잡한 소프트웨어 조각이며 잘못된 사용으로 인해 비정상적인 행동을 보일 수 있습니다.

+0

제발 내 코드에서이 일을 설명해주세요. "(예를 들어, 블록이 실제로 요청한 것보다 크기 때문에 realloc은 메모리를 다시 할당하지 않아도 괜찮다고 생각하기 때문입니다.) –

+0

malloc에 ​​세분성이 있습니다 이는 시스템마다 다르지만 일반적으로 약 16 바이트입니다. realloc (ptr, 5), 당신은 아래에 있고 할당 된 블록의 크기 (16 바이트)는 생각하는 크기보다 작습니다. – PypeBros

+0

당신의 코드를 어떻게 고칠 수 있는지에 대한 설명은 joachim의 대답이 될 것입니다. 당신은 또한 "왜 5로 ..."에 의문을 제기했고, 나는 할당 자의 내부 작업을 더 잘 알고 있다고 생각했습니다. – PypeBros

0

감사합니다. 도움이되었습니다.

group_name = realloc(NULL, sizeof *group_name); 
    grp_nm = realloc(grp_nm, grp_cn * sizeof *grp_nm); 

그 이후에 libc 오류가 완료되었습니다. 하지만 어쨌든 main()에서 서브 루틴에 배열이 채워진 후 값을 읽을 수 없습니다. group_name 값을 읽을 수 없습니다. [3] 가정 해 봅시다. 서브 루틴에서 grp_nm [3]은 서브 루틴의 배열 group_name에 포인터를 전달할 때 매우 잘 표시됩니다. 내가 발견 한 이유는 나머지 메모리와 충돌하는 경우 realloc 동안 전체 배열을 새로운 locaion으로 다시 정의하여 배열에 대한 포인터를 변경한다는 것입니다.예 내가 초 재 할당 grp_nm 첫 재분배 grp_nm = 0x5689F0 에 루틴, 로 패스 = 0x5689F0 메인 GROUP_NAME에서 = 0x5689F0

어레이 grp_nm의 위치에서 메모리 충돌 변화로 인해 일부 재분배 후에

0x345FF1이됩니다. 그래서 난이

 group_name=group_count(object, count, group_name);  

같은 서브 루틴에서이 포인터를 reuturn해야하므로 포인터 변화가 업데이트 될 경우 지금 GROUP_NAME = 0x345FF1