[c언어] calloc 동적메모리 잡은후 문자열출력 에러

devanix의 이미지

  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) 입니다.

정확한 원인을 알고싶습니다.
친절한 답변 부탁드립니다. ㅜㅜ

ymir의 이미지

*(++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 』

cppig1995의 이미지

"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.

ikpil의 이미지

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] 을 해체하려 하니, 알수 없는 행동을 하게 된 것으로 보입니다.
그래서 리눅스나 윈도우나 오류가 날수도 있고 안날수도 있는것으로 판단됩니다.

전 어디까지나 추측이랍니다.

댓글 달기

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