2010-04-26 2 views
1

У меня есть структура, определяемая следующим образом:Исключение на таНос для структуры в C

typedef struct { 
int n; 
int *n_p; 
void **list_pp; 
size_t rec_size; 
int n_buffs; 
size_t buff_size 
} fl_hdr_type; 

и в моем коде у меня есть функция для initlialization, которая имеет следующий

fl_hdr_type *fl_hdr; 
fl_hdr = malloc(sizeof(fl_hdr_type) + (buff_size_n * rec_size_n)); 

где те буфера размер передается функции, позволяющей также пространство для буферов.

Размер довольно маленький типично.100 * 50 или что-то в этом роде. Много памяти в этой системе, чтобы выделить его. я не могу на самом деле размещать трассировки стека, поскольку этот код в другой сети, но некоторая информация извлекается из DBX на основной файл:

buff_size_n = 32, rec_size_n = 186

и stack..line номера от malloc.c

t_splay:861 
t_delete:796 
realfree: 531 
cleanfree:945 
_malloc:230 
_malloc:186 

Любые идеи, почему это не удается?

+0

Каково конкретное значение buff_size_n и rec_size_n, когда оно не работает? Что происходит, когда он терпит неудачу, вы терпите крах, или malloc возвращает NULL, или ...? – nos

+2

Вы уверены, что это вызов «malloc», который терпит неудачу? Может ли 'buff_size_n' или' rec_size_n' быть отрицательное значение? Вы пытались заменить 'malloc (sizeof (...) + ...)', например. 'ТаНос (5000)'? – stakx

+4

c не имеет исключений – 2010-04-26 17:31:06

ответ

8

Попробуйте запустить программу через valgrind, посмотрите, что она сообщает. Возможно, в какой-то другой части программы у вас есть испорченные бесплатные списки или что-то еще, на что смотрит malloc.

+4

+1 Если программа рушится * внутри * 'malloc', практически гарантировано, что вы повредили кучу в другом месте. –

0

Что вам нужно сделать, так это просто сделать это.

fl_hdr = malloc (sizeof (fl_hdr_type)); list_pp - это динамический массив void *, и вам нужно выделить его по размеру с помощью другого malloc.

list_pp - это просто указатель на что-то еще, выделенное на кучу.

Если вы хотите выделить на месте один malloc, вам нужно будет определить его как массив фактических типов, которые вы хотите. Компилятор должен знать типы, которые могут выполнять распределение.

Если вы ищете динамические массивы в C, then look at this.

+0

Кроме того, вам необходимо сделать это, чтобы сузить причину проблемы. – Puppy

+0

обновленный OP с дополнительной информацией – Derek

0

Я сделал ваш пример в программе и не имею абсолютно никаких проблем с его запуском. Если вы можете скомпилировать и запустить этот простой код (и он работает), вы повредили кучу где-то еще в своей программе. Пожалуйста, запустите его через Valgrind ( как User275455, я не заметил ответа) и обновите свой вопрос с помощью вывода, который он вам дает.

Редактировать

Кроме того, пожалуйста, обновите ваш вопрос, чтобы указать точно то, что вы делаете с **list_pp и *n_p после выделения структуры. Если у вас нет доступа к valgrind, по крайней мере вставьте всю трассировку, которую glibc распечатал, когда программа разбилась.

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

typedef struct { 
int n; 
int *n_p; 
void **list_pp; 
size_t rec_size; 
int n_buffs; 
size_t buff_size; 
} fl_hdr_type; 

static size_t buff_size_n = 50; 
static size_t rec_size_n = 100; 


static fl_hdr_type *my_init(void) 
{ 
     fl_hdr_type *fl_hdr = NULL; 
     fl_hdr = malloc(sizeof(fl_hdr_type) + (buff_size_n * rec_size_n)); 

     return fl_hdr; 
} 

int main(void) 
{ 
     fl_hdr_type *t = NULL; 

     t = my_init(); 

     printf("Malloc %s\n", t == NULL ? "Failed" : "Worked"); 

     if (t != NULL) 
      free(t); 

     return 0; 
} 
+0

Обновлен OP с подробными сведениями, которые я могу получить из основного файла, но у нас нет valgrind на этой системе. Вам придется заглянуть в это вскоре. – Derek

+0

И если вы запустите эту программу самостоятельно, это не сработает ? –

+0

@Derek - см. Мои правки. –

0

Вам необходимо явно назначить n_p и list_pp к соответствующим смещениям.

fl_hdr_type *fl_hdr; 
fl_hdr = malloc(sizeof(fl_hdr_type) + (buff_size_n * rec_size_n)); 
fl_hdr->n_p = fl_hdr+sizeof(fl_hdr_type); 
fl_hdr->list_pp = fl_hdr->n_p + (num_n * sizeof(int)); 

Если вы собираетесь сделать это, я бы рекомендовал поставить указатели в конце структуры, а не по центру. Тем не менее, я с Романом и рекомендую использовать отдельные вызовы для malloc() вместо того, чтобы хватать все одним звонком.

+0

Выделение всего в одном вызове помогает уменьшить фрагментацию кучи. Кроме того, он несколько эффективнее. Они не являются основными причинами сами по себе, но они могут стать важными в некоторых контекстах. Если вы применяете подход с одним распределением, вы должны быть уверены, что память сразу после '* fl_hdr' правильно выровнена для всего, что она содержит. –

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