[c언어] calloc 동적메모리 잡은후 문자열출력 에러
글쓴이: devanix / 작성시간: 토, 2008/05/03 - 7:29오전
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 5 int main(void){ 6 7 char *str[3] = {"Unix", "Linux", "Window"}; 8 char **pps; 9 int i; 10 11 if( (pps = (char**) calloc (3, sizeof(char*))) == NULL){ 12 fprintf(stderr, "calloc() error!"); 13 return -1; 14 } 15 16 for(i=0; i<3; i++){ 17 *(pps+i) = str[i]; 18 } 19 20 printf("%s ", *(++pps)); 21 22 putchar('\n'); 23 free(pps); 24 25 return 0; 26 }
위의 소스를 출력하면
Linux *** glibc detected *** ./ex: free(): invalid pointer: 0x089bd00c *** ======= Backtrace: ========= /lib/libc.so.6[0x4e4acefd] /lib/libc.so.6(cfree+0x90)[0x4e4b0550] ./ex[0x804852c] /lib/libc.so.6(__libc_start_main+0xdc)[0x4e45cf2c] ./ex[0x80483b1] ======= Memory map: ======== 001ec000-001ed000 r-xp 001ec000 00:00 0 [vdso] 08048000-08049000 r-xp 00000000 03:07 1145295 /home/devanix/programming/cstudy/ex 08049000-0804a000 rwxp 00000000 03:07 1145295 /home/devanix/programming/cstudy/ex 089bd000-089de000 rwxp 089bd000 00:00 0 4da78000-4da91000 r-xp 00000000 03:05 1520765 /lib/ld-2.5.so 4da91000-4da92000 r-xp 00018000 03:05 1520765 /lib/ld-2.5.so 4da92000-4da93000 rwxp 00019000 03:05 1520765 /lib/ld-2.5.so 4e447000-4e57e000 r-xp 00000000 03:05 1520766 /lib/libc-2.5.so 4e57e000-4e580000 r-xp 00137000 03:05 1520766 /lib/libc-2.5.so 4e580000-4e581000 rwxp 00139000 03:05 1520766 /lib/libc-2.5.so 4e581000-4e584000 rwxp 4e581000 00:00 0 4fb3a000-4fb45000 r-xp 00000000 03:05 1519075 /lib/libgcc_s-4.1.2-20070626.so.1 4fb45000-4fb46000 rwxp 0000a000 03:05 1519075 /lib/libgcc_s-4.1.2-20070626.so.1 b7e00000-b7e21000 rw-p b7e00000 00:00 0 b7e21000-b7f00000 ---p b7e21000 00:00 0 b7f73000-b7f74000 rw-p b7f73000 00:00 0 b7f8c000-b7f8e000 rw-p b7f8c000 00:00 0 bfba4000-bfbb9000 rw-p bfba4000 00:00 0 [stack]
위와 같이 Linux를 출력후 (세그먼트???)에러종료 되는데요
소스코드 20번줄을 printf("%s ", *(pps+1)); 을하면 정상 출력이 되는데
printf("%s ", *(++pps)); 와 같이 하면 위와같이 출력되면서 에러종료가 되네요.
근데 이상한건 windows 환경에서는 에러가 안나고 정상출력되네요.
현재 Fedora6(gcc 버전 : 4.1.2) 입니다.
정확한 원인을 알고싶습니다.
친절한 답변 부탁드립니다. ㅜㅜ
Forums:
음...
*(++pps) 때문에.. pps 의 값 자체가 바뀌었습니다..
엉뚱한 주소값을 free() 하려니, 에러가 발생하는겁니다..
pps 의 값은 바뀌지 않도록 유지하시고, 별도의 변수를 사용해서 연산을 하시거나..
*(pps+i) 처럼 원래 포인터에 대한 offset 을 쓰시면 되겠네요..
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
"Windows가 Windows라서
"Windows가 Windows라서 그렇습니다."라는 답변밖에 없습니다. : )
동적 메모리 할당의 세부 구현 사항은 운영체제와 라이브러리별로 상당히 다르게 마련이죠.
--
돼지군 작업실: 4word 64bit OS, IMPerator, SMPlayer 한국어 번역, ...
대전월평중 2 / Ubuntu Hardy / 070) 7594-3258 / 서명 변경일 2008/4/9
Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.
저는 윈도우에서 .. 테스트 했는데, 오류 납니다.
if( (pps = (char**) calloc (3, sizeof(char*))) == NULL)
이때 pps는 3개의 char* 를 담는 배열과 비슷한 형태를 취하게 됩니다.
(내부적으로 배열인지는 모르겠습니다. 비슷한 형태로 된다는것만 추측할뿐입니다;)
그래서,
pps[0] pps[1] pps[2] 처럼 쓸수 있는데요.
pps가 한칸 앞당겨 짐으로써
pps[1] pps[2] pps[3] 형식으로 바뀌였는데.
free로
pps[1] pps[2] pps[3] 을 해체하려 하니, 알수 없는 행동을 하게 된 것으로 보입니다.
그래서 리눅스나 윈도우나 오류가 날수도 있고 안날수도 있는것으로 판단됩니다.
전 어디까지나 추측이랍니다.
http://www.ikpil.com
댓글 달기