あなたのコードのバグは次のとおりです。processFile() 関数を呼び出すとアドレスの割り当てnewNode->Data->FName
が無効になりfree(input)
、空きメモリにアクセスすると、実行時に「未定義の動作」が発生します。
コードを修正するには:
次のような単純な代入の代わりに:
newNode->Data->FName = strtok(input," ");
以下のように別のメモリに割り当ててコピーします。
char *ptr = strtok(input," ");
newNode->Data->FName = malloc(strlen(ptr)+1);
strcpy(newNode->Data->FName, ptr);
実際にはinput
addOrdered() でアドレス空間からメモリアドレスを割り当てていてfree()
、 processFile()
関数を作ります。
以下にコードを詳しく説明します。
最初の読み取り: char * strtok ( char * str, const char * delimiters ); マニュアル:
最初の呼び出しでは、関数は str の引数として C 文字列を予期します。その最初の文字は、トークンをスキャンする開始位置として使用されます。後続の呼び出しでは、関数は null ポインターを予期し、最後のトークンの末尾の直後の位置をスキャンの新しい開始位置として使用します。
戻り値
文字列で見つかった最後のトークンへのポインター。取得するトークンが残っていない場合は、null ポインターが返されます。
新しいメモリを送信するのではなく、input
最近 free() したメモリを送信します。strtok() 関数の動作を理解するために、次のコードを書きました。
int main (){
char str[] ="- This, a sample string.";
printf("str address: %p, ends on: %p \n", str, str+strlen(str));
printf ("Splitting string \"%s\" into tokens:\n",str);
char * pch;
pch = strtok (str," ,.-");
while (pch != NULL){
printf ("pch: %7s, address: %p\n",pch, pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
上記のプログラムの実行 (アドレスは実行ごとに異なる場合があります):
~$ ./a.out
str address: 0x7fff96958d50, ends on: 0x7fff96958d68
Splitting string "- This, a sample string." into tokens:
pch: This, address: 0x7fff96958d52
pch: a, address: 0x7fff96958d58
pch: sample, address: 0x7fff96958d5a
pch: string, address: 0x7fff96958d61
注意:アドレスは アドレス scapepch
から/内にあります。str
newNode->Data->FName = strtok(input," ");
コードでも同様に、関数内に割り当てaddOrdered()
ます。のメモリアドレス値 newNode->Data->FName
は、後で関数input
内で解放するため、無効になり、コードは未定義の動作として実行されますprocessFile()
newNode->Data->FName
void addOrdered(Node ** Head,char * input){
printf("\nInput: %s\n",input);
// some code here
step-2
newNode->Data->FName = strtok(input," "); <--"assign memory"
^
// Some code here |
} |
|
void processFile(Node ** Head, FILE * fd){ | step-1
char * input = malloc(sizeof(char)*SIZE); <-|----"Allocate memory"
while(fgets(input,SIZE,fd) != NULL){ |
addOrdered(Head,input); -----------------
} step-3
free(input); <-----------------------------------"Free memory"
}
So, "What is assign to newNode->Data->FName becomes invalid"
次に、バッファ内のファイルから 1 つ少ない文字を読み取り、 null 用のスペースを確保する必要があります\0
。
fgets(input, SIZE-1, fd)