2011-12-22 10 views
2

ローカルとして宣言されたときにポインタでセグメンテーションフォルトが発生します。プログラムは長すぎてここにコピーできませんが、次のようなものです:ポインタがローカルの場合のセグメンテーションフォールト

void f(){ 
    int* p; 
    int n = 0; 
    for (...) { 
     n++; 
     p = realloc(p, n * sizeof(int)); 
     if (p == NULL) error(); 
    } 
    //Code using the pointer 
    free(p); 
} 

int main() { 
    f(); 
    puts("Finish"); 
} 

puts( "Finish");私はこの後にセグメンテーションフォルトを取得します。

funcionの前にpをグローバルとして宣言すると、フォルトなしで完全に動作し、この問題は解決しますが、なぜこのようなことが起こっているのかわかりません。

デバッガの実行問題がどこにあるか分かりません。すべての値がわかりました。 (...フォーク、EXECV、など)あなたの答えを事前に

おかげで、それは問題になる可能性が念のために

Program received signal SIGSEGV, Segmentation fault. 
0x000000361206dbd1 in _IO_flush_all_lockp() from /lib64/libc.so.6 
(gdb) bt 
#0 0x000000361206dbd1 in _IO_flush_all_lockp() from /lib64/libc.so.6 
#1 0x000000361206e725 in _IO_cleanup() from /lib64/libc.so.6 
#2 0x00000036120334b2 in exit() from /lib64/libc.so.6 
#3 0x000000361201d99b in __libc_start_main() from /lib64/libc.so.6 
#4 0x0000000000400ce9 in _start() 

、it'sマルチアプリケーション:これは、故障した後のトレースであります

答えて

6

pの初期化に気を使わないように見えます - グローバル変数では暗黙的に0に初期化されますが、ローカル変数は初期化されません。したがって、ヒープを破損し、後でクラッシュするランダムなガベージ・ポインタをrealloc/freeと呼ぶことになります。

pを初期化する必要があります。ループの最初の繰り返しで

+1

ありがとう、それは問題でした。単純なint * p = NULLはそれを修正しました。 – Evans

1
int* p; 
// ... 
for (...) { 
//... 
     p = realloc(p, n * sizeof(int)); 

あなたはそれを初期化していないため、pの値が誤った定義になっています。これはエラーです。それがあなたの問題の原因であるかどうかは確信していませんが、まずそれを修正して、問題が解決しないかどうかを確認します。

0

reallocのドキュメントを参照してください。それはここから入手可能です:

http://pubs.opengroup.org/onlinepubs/7908799/xsh/realloc.html

奪う事はNULLポインタ(0を指し、すなわち、ポインタ)でrealloc()を呼び出すことが有効であるということです。しかし、mallocまたはcallocを使用して取得されなかったnull以外のポインタで呼び出すと、「未定義」の動作が発生します。

これはどうしてですか? pをグローバルスコープで宣言すると、0(つまりNULL)に初期化されるため、ローカルスコープで宣言されている場合、これは起こらないかもしれません。代わりに明示的に初期化しないと、任意の初期値を持つことになり、前述の "未定義の動作"が発生します。

関連する問題