dポイントプレゼントキャンペーン実施中!

プログラムの作成をしたのですが、
自宅(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;
}
――――――――――――――――――――――――――
以上です。

A 回答 (6件)

落ちているところは、


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した後にメモリを利用しても、ポインタは消えないので事実上問題はありません。
プログラムとしてはよろしくありませんが...
    • good
    • 0
この回答へのお礼

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

お礼日時:2001/01/24 16:05

#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)と表示してくれますね。
    • good
    • 0

う~ん、、、


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のメモリ管理が
杜撰すぎるだけです。
    • good
    • 0

ここでmemfreeしちゃだめです。


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

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

    • good
    • 0

今Linux上でコンパイルして実行してみたのですが特に


core dump しません...

core dumpする時に入力データとして何をわたしていますか?

あと、学校の端末で

gcc -g -o strtest strtest.c
gdb strtest

等としてソースコードレベルでデバッグするとわかるかと思います。
OSは、uname -a とかするとわかると思います。

この回答への補足

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

以上です。

補足日時:2001/01/23 01:40
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!