2016-10-14 2 views
0

私はmallocを使っていくつかの非常に奇妙な動作をしています。私は4kB以上を割り当てることはないので、これは私にとっては特に奇妙なことです。私の主は、次のようになります。mallocのポインタ自体がNULLにリセットされていますか?

int main(int argc, char **argv) 
{ 
    char *buf; 
    char *raw = malloc(1024); 
    fgets(raw, 1024, stdin); 

    parse(raw, &buf); // Process raw input, get parse length 

    printf("raw: 0x%p\n", raw); // Outputs 0x00000000 

    if(raw != NULL) 
    { // Only prints when less than 10 characters are entered 
     free(raw); 
     printf("raw is not NULL\n"); 
    } 
    free(buf); 
    return 0; 
} 

私が10個の未満の文字を入力すると、私は私がセグメンテーションフォールトを取得し、正確に10文字を入力したときに、これは、大丈夫働く、と私は10以上のものを入力したときに出力が生がNULLであることを示しています。 rawのサイズは1024 mallocされたバイトであることに注意してください。

解析関数である:

int parse(char *src, char **dst) 
{ 
    int num_valid = 0, len = strlen(src), j = 0; 

    // Count number of valid characters 
    for(int i = 0; i < len; i++) 
    { 
     if(src[i] == 'A') 
      ++num_valid; 
    } 

    *dst = malloc(num_valid); 

    for(int i = 0; i < len; i++) 
    { 
     if(src[i] == 'A') 
      *dst[j++] = src[i]; 
    } 

    // For debugging: 
    printf("src: 0x%p\n", src); // outputs correct address 

    return num_valid; 
} 

この関数は、正しいアドレスを出力し、適切に割り当て、DSTを満たします。ここでコードを少し修正しました。これは基本的に私のコードの非常に縮小された形です。同じ結果を得てコンパイルして実行しました(gcc test.c -Werror -Wall)。この関数が、生のポインタがNULLになったことを返すか、またはsegfaultを取得した後です。

誰かが正しい方向に向かうことができますか?私が間違っていることを正確に教えてください。私は昨日からこの小さなコードをデバッグしていて、それが私を怒らせています。

+0

場合は、Linuxの使用valgrindの – pm100

+0

こんにちは上でコアダンプがスタックトレースを表示するために使用GDBを作成された場合どこが落ちているのか正確に見てみましょう。 –

答えて

6

これは、あなたがそれが意味どう思うかという意味ではありません:

*dst[j++] = src[i]; 

をあなたは

あなたは手段を書いた何
(*dst)[j++] = src[i]; 

を意味:

*(dst[j++]) = src[i]; 

dst[1]は従うことを起こるものは何でもあります変数bufですので、ランダムなメモリ位置からアドレスを使用していますそれが指し示すものであれば何でも上書きすることができます。それは未定義の振る舞いです。

@ PM100は、コメントで指摘するように、一時的な変数でバッファを維持することは、一般的に、より良いスタイルです:

char* buf = malloc(num_valid); 
if (!buf) { /* Handle allocation failure */ } 
*dst = buf; 
/* ... */ 
    /* In loop */ 
    buf[j++] = src[i]; 
+1

私はいつも '* dst'を' char * buf'の一時ポインタに入れます – pm100

+0

ありがとう!私はこれが原因であると確信しています。私は誤ってどこかのsrcのアドレスを上書きしたに違いありません。 –

+0

@ pm100:良い点。答えに追加されました。 – rici

関連する問題