malloc, вызывающий SIGSEGV: ошибка сегментации - PullRequest
3 голосов
/ 17 декабря 2010
typedef struct Matrix
{
    double * matrix;
    int sizex;
    int sizey;
}Matrix;

int nn = 257;
Matrix * g = (Matrix *)malloc(sizeof(Matrix *));
g->matrix = malloc(sizeof(double) * nn * nn);
g->sizex = nn;
g->sizey = nn;

Этот код выдает ошибку при достижении g->matrix = malloc(sizeof(double) * nn * nn); кто-нибудь видит проблему с ним?

edit: обнаружена проблема с доступом к нераспределенной памяти в месте до показанного выделения, это быловызывая SIGSEGV: ошибка сегментации.

Ответы [ 7 ]

6 голосов
/ 17 декабря 2010

Вам нужно передать malloc размер Matrix не sizeof указатель на Matrix.

Изменить

Matrix * g = (Matrix *)malloc(sizeof(Matrix *));
                                           ^^ 

на

Matrix * g = (Matrix *)malloc(sizeof(Matrix));

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

0 голосов
/ 17 декабря 2010

Я просто добавлю направление, чтобы не приводить возвращение Маллока. Это является ненужным, загрязняющим веществом и может привести к нежелательному поведению (как описано здесь: http://c -faq.com / malloc / mallocnocast.html

0 голосов
/ 17 декабря 2010

Параметр вашего sizeof не должен быть указателем.

0 голосов
/ 17 декабря 2010

Вы не выделяете память для объекта Matrix, вы выделяете указатель.

Измените свой первый malloc вызов, чтобы сделать это:

Matrix * g = malloc(sizeof(*g));

Я предпочитаю этот стиль, так как вам не нужно явное приведение указателя из void * в C, и вам разрешено делать sizeof для базового типа переменной.Это может избавить вас от головной боли на случай, если вы измените тип g (или для будущего кода).

Аналогично стилю:

g->matrix = malloc(sizeof(double) * nn * nn);

:

g->matrix = malloc(sizeof(*(g->matrix)) * nn * nn);

0 голосов
/ 17 декабря 2010
Matrix * g = (Matrix *)malloc(sizeof(Matrix *));

должно быть

Matrix * g = (Matrix *)malloc(sizeof(Matrix));

Вы только назначаете размер указателя на матрицу, а не саму матрицу.

0 голосов
/ 17 декабря 2010
Matrix * g = (Matrix *)malloc(sizeof(Matrix *)); 

Это резервирует достаточно места в куче для указателя на матрицу, но вы хотите достаточно места в куче для самой матрицы.Попробуйте:

Matrix* g = (Matrix*)malloc(sizeof(Matrix)); 

Для полной работающей программы:

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

typedef struct Matrix {
    double * matrix;
    int sizex;
    int sizey;
} Matrix;

int main()
{
    int nn = 257;
    Matrix * g = (Matrix *)malloc(sizeof(Matrix));
    if (g == NULL)
    {
        printf("g = malloc() failed\n");
        return 1;
    }
    g->matrix = malloc(sizeof(double) * nn * nn);
    g->sizex = nn;
    g->sizey = nn; 
    printf("g %p, g->matrix %p, g->sizex %d, g->sizey %d\n",
            g, g->matrix, g->sizex, g->sizey);
    return 0;
}

Вывод на мой компьютер Linux:

g 0x8822008, g->matrix 0xf6ea6008, g->sizex 257, g->sizey 257
0 голосов
/ 17 декабря 2010

Я предполагаю, что вы используете какой-то древний 16-битный компилятор, возможно, Turbo C. Удалите его и получите gcc, либо djgpp, если вы хотите создавать программы для DOS, либо mingw или cygwin, если вы хотите создавать программы для Windows. 1001 *

Предполагая, что я прав, 257 * 257 переполняет максимальный адресуемый размер, 65536, не говоря уже о том, что происходит, когда вы умножаете его на 8.

Редактировать: ОП изменил вопрос после того, как я написал это, так что он может быть полностью отключен. Если так, я удалю его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...