2015-12-14 4 views
3

Является ли ошибка сегментации в конце кода (только для выделения памяти в 2D-массив и печати результата)? Заканчивается последний оператор printf, и любой код, который я добавляю в конце, успешно завершается, а затем появляется segfault.Ошибка сегментации в конце программы C

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int n,i,j,**mat; 

    printf("\nEnter the size of the square matrix: "); 
    scanf("%d",&n); 

    *mat = (int **)malloc(n*sizeof(int *)); 

    for(i=0;i<n;i++) 
    { 
     mat[i]= (int *)malloc(n*sizeof(int)); 
    } 

    for(i=0;i<n;i++) 
    { 
     for(j=0;j<n;j++) printf("%d\t",mat[i][j]=rand()%10*i+j); 
     printf("\n\n\n"); 
    } 

    printf("Bye\n"); 
    return 0; 
} 

Технически *mat в 8-й строке (напечатанной в коде), должны быть mat, но потом все нормально. Указанный код компилируется (с очевидным предупреждением о несовместимом типе указателя в gcc) и работает, кроме как в конце, когда он печатает segfault. Если бы в программе было segfault, это не дошло бы до конца!

+0

Одним из возможных объяснений является то, что адрес возврата из 'main' был перезаписан в стеке, поэтому он дает segfault в конце функции' main'; вероятно, из-за неправильного использования указателя. – m0skit0

+6

Поскольку вы, по-видимому, знаете, что «' * mat' в 8-й строке (напечатан в коде) должен быть «матом», что именно ваш вопрос? –

+2

Ваше использование '* mat' вызывает неопределенное поведение. Переменная 'mat' неинициализирована; вы разыгрываете его. Все может случиться.Код сломан. В любом случае, вы должны были использовать 'mat = malloc (n * sizeof (* mat));' если вы не используете компилятор C++ для компиляции C, в этом случае вам нужен приведение. –

ответ

4
*mat = (int **)malloc(n*sizeof(int *)); 

должен быть

mat = (int **)malloc(n*sizeof(int *)); 

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

Также нет необходимости выдавать возвращаемое значение malloc. Here - это пара причин, почему вы, вероятно, не шутите.

+3

Он уже знает это: * «Технически * коврик в 8-й строке (напечатан в коде) должен быть матом» * – m0skit0

+1

Ударьте меня тоже>. <Эта ошибка mallocing не объясняет, почему его код все еще работает до последнего 'printf' заявление. – SpencerD

+1

@SpencerDoak: неопределенное поведение означает, что все может случиться, в том числе вещи, видимо, работающие намного лучше, чем вы имеете право ожидать. Кажется, это происходит здесь. –

1

*mat = (int **)malloc(n*sizeof(int *)); является разыменование нераспределенного указателя. Это приводит к непредсказуемому поведению ...

Неопределенное означает все, что может случиться. Прочитайте this. Возможно, вы не видите результаты вашего плохого де-распределения до конца вашей программы.

В качестве дополнительной записке, you should not cast the result of malloc .so следующее:

*mat = (int **)malloc(n*sizeof(int *)); 

должен быть заменен:

mat = malloc(n * sizeof mat*); 

Наряду с некоторыми изменениями в остальной части вашей линии распределения памяти.

+0

Далее: предложите стиль 'mat = malloc (sizeof * mat * n);'. – chux

3

Чтобы ответить на ваш вопрос, причина, по которой вы получаете ошибку сегментации после, функция main() состоит в том, что стек поврежден.

stack pointer был перезаписан, что означает, что при попытке main() возвращать указатель стека содержит недопустимое значение. Это заставляет вашу программу пытаться получить доступ к памяти за пределами адресного пространства процесса. Если вы используете exit (0), вы можете может избежать ошибки сегментации.

Имейте в виду, что ваша программа приводит к неопределенному поведению. Иногда вы получаете ошибку сегментации в конце, иногда во время выполнения, иногда вообще нет (и могут возникать всевозможные другие странные вещи).

+0

Во время отладки я попытался добавить инструкции printf для получения адресов, и я был удивлен, увидев, что добавление printf-инструкции (не печатать ничего, кроме & mat) устраняет segfault. printf («% p \ n», &mat); Кроме того, я запускал код времени в бесконечном цикле, он согласован. –

+0

Вы добавили инструкции printf после выделения карты в цикле? (строка 13 в основном). –

+0

P.2 перед * mat = malloc (n * sizeof (int *)); –

Смежные вопросы