• ベストアンサー

処理系によって。

プログラムの作成をしたのですが、 自宅(VisualC++)だと実行できるのに、 学校の端末(OSしかわかりませんが、UNIXです。) だと、core dumpedしてしまいます。 どういう原因が考えられるでしょうか? プログラムソースは次の通りです。 ―――――――――――――――――――――――――― #include<stdio.h> #include<stdlib.h> char *strtok(char *moji, char cc); void main() { char moji[200]; char kugiri[10]; char *cp; printf("文字列を入力してください\n"); scanf("%s",moji); printf("区切り文字を入力してください\n"); scanf("%s",kugiri); cp=strtok(moji,kugiri[0]); printf("取り出した文字列は%s\n",cp); while(cp!=NULL){ cp=strtok(NULL,kugiri[0]); printf("取り出した文字列は%s\n",cp); } } char *strtok(char *moji,char cc) { int len; char *cp1,*cp2; char *mem; static char *moji_old; if(moji==NULL){ moji=moji_old; }      len=0; cp1=moji; while(*cp1!='\0'){ len++; cp1++; } mem=malloc(len+3); if(mem==NULL){ puts("メモリが足りません\n"); return NULL; } cp1=moji; cp2=mem; while(*cp1!=cc && *cp1!='\0'){ *cp2=*cp1; cp1++; cp2++; } free(mem); if(*cp1=='\0'){ moji_old=cp1; mem=NULL; } else{ moji_old=cp1+1; *cp2='\0'; } return mem; } ―――――――――――――――――――――――――― 以上です。

質問者が選んだベストアンサー

  • ベストアンサー
  • madman
  • ベストアンサー率24% (612/2465)
回答No.4

落ちているところは、 while(cp!=NULL){ cp=strtok(NULL,kugiri[0]); printf("取り出した文字列は%s\n",cp);←ここです。 } strtok()関数がバグっています。 入力した文字列の最後に;がないので、 if(*cp1=='\0'){ moji_old=cp1; mem=NULL; } 最後の'lmn'がこの判定に入ってしまい、NULLをリターンします。 このNULLをprintfで表示しようとするので、coredumpとなります。 回避は、この分岐内でも、'mem=NULL;'ではなく'*cp2='\0';'としましょう。 他の方が指摘しているfreeした後にメモリを利用しても、ポインタは消えないので事実上問題はありません。 プログラムとしてはよろしくありませんが...

g_oldman
質問者

お礼

ありがとうございます。 よくわかりました。

その他の回答 (5)

  • madman
  • ベストアンサー率24% (612/2465)
回答No.6

#include <stdio.h> #include <stdlib.h> main() { static char *aa; aa = malloc(5); strcpy(aa, "abc"); free(aa); printf("%s\n", aa); sleep(2); strcat(aa, "de"); printf("%s\n", aa); sleep(2); aa = NULL; printf("%s\n", aa); } と書くと、abcと表示し、2秒後にabcdeと表示し、2秒後にcoredumpしますよ。 因みにgdbの内容 (gdb) where #0 0xef723d50 in strlen () #1 0xef761f8c in _doprnt () #2 0xef76ad60 in printf () #3 0x10a00 in main () at b.c:21 (gdb) list 21 16 strcat(aa, "de"); 17 printf("%s\n", aa); 18 19 sleep(2); 20 aa = NULL; 21 printf("%s\n", aa); 22 } solarisで純正コンパイラ。 linux gcc では、coredumpせずに(nul)と表示してくれますね。

  • selenity
  • ベストアンサー率41% (324/772)
回答No.5

う~ん、、、 core dumpの理由は、strtok()内で mem=malloc();した後、cp2=mem;と代入してますね。 その後、free(mem);を実行しておきながら、 *cp2='\0';をやってますね。 このとき*cp2(mem)がallocateしていたメモリ 開放されています。 だから、Segmentation Faultなのです。 つまり、「アクセスしてはいけない領域に アクセスしようとした」のです。 *cp2='\0';とやっても、free(mem);をする以上、 Segmentation Faultです。 よって、ある意味、mem=NULLは正しいともいえます。 また、printf("%s", NULL);ではエラーは発生しませんよ! 全く問題なく正常に動作します。 VCで動くのはWindowsとVCのメモリ管理が 杜撰すぎるだけです。

  • selenity
  • ベストアンサー率41% (324/772)
回答No.3

ここでmemfreeしちゃだめです。 その後で*cp2='\0';をしてるので、ここで SegmentationFaultが発生します。 また、return mem;をする場合は、呼び出し先で メモリ開放しちゃだめです。 また、moji_oldもできるだけstrtok内でalloc/free し、アドレスの代入ではなくメモリーコピーしましょう。

  • shigatsu
  • ベストアンサー率26% (511/1924)
回答No.2

えーっと free(mem) したあとに return mem してるんですが、それはOKですか?

  • h_hikita
  • ベストアンサー率40% (104/257)
回答No.1

今Linux上でコンパイルして実行してみたのですが特に core dump しません... core dumpする時に入力データとして何をわたしていますか? あと、学校の端末で gcc -g -o strtest strtest.c gdb strtest 等としてソースコードレベルでデバッグするとわかるかと思います。 OSは、uname -a とかするとわかると思います。

g_oldman
質問者

補足

実行時に表示されるのは次の通りです。 nagatsuki% report2 文字列を入力してください bcde;efgh;;ijk;;lmn 区切り文字を入力してください ; 取り出した文字列はbcde 取り出した文字列はefgh 取り出した文字列は 取り出した文字列はijk 取り出した文字列は Segmentation fault (core dumped) 以上です。

関連するQ&A