Ошибка сегментации, когда указатель является локальным - PullRequest
2 голосов
/ 22 декабря 2011

Я получаю ошибку сегментации с указателем, когда он объявлен как локальный.Программа слишком длинная, чтобы скопировать ее сюда, но она выглядит примерно так:

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");
}

put ("Finish");выполняется, но я получаю ошибку сегментации после этого.

Если я объявлю p глобальным, перед функцией он будет работать без сбоев, и эта проблема будет решена, но я не знаю, почему это происходит.

Запустить отладчик я не могуПосмотрите, где проблема, все значения кажутся в порядке.Это след после сбоя:

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 ()

На случай, если это может быть проблемой, это многопроцессорное приложение (fork, execv и т. Д ...)

Спасибо зазаранее за ваши ответы

Ответы [ 3 ]

6 голосов
/ 22 декабря 2011

Похоже, вы не удосужились инициализировать p - для глобальной переменной она будет неявно инициализирована равной 0, а для локальной переменной - нет.Таким образом, вы в конечном итоге вызываете realloc / free со случайным указателем мусора, который повреждает кучу и вызывает последующий сбой ...

Инициализируйте p и это должно исправить.

1 голос
/ 22 декабря 2011
int* p;
// ...
for (...) {
//...
       p = realloc(p, n * sizeof(int));

На первой итерации цикла значение p не определено, поскольку вы его не инициализировали. Это ошибка Не уверен, что это является причиной вашей проблемы, но я сначала исправлю это и посмотрю, не исчезнет ли проблема.

0 голосов
/ 22 декабря 2011

Вам следует проверить документацию на realloc. Это доступно здесь:

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

Важно отметить, что вызов realloc() с указателем NULL (т. Е. Указателем, который указывает на 0) является допустимым. Однако вызов его с ненулевым указателем, который не был получен с помощью malloc или calloc, вызывает поведение «неопределенное».

Так почему это важно? Потому что когда вы объявляете p в глобальной области видимости, он будет инициализирован для вас 0 (т. Е. NULL). Когда это объявлено в локальной области видимости, это не может произойти. Вместо этого он будет иметь произвольное начальное значение, если вы не инициализируете его явно, и это вызовет вышеупомянутое «неопределенное поведение».

...