2010-04-26 62 views
1

I的结构所定义的结构,如下所示:异常上的malloc在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; 

和在我的代码我有一个函数,该函数具有以下

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

initlialization其中那些缓冲大小被传递给函数以允许缓冲区的空间。

大小是非常小的通常..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 2010-04-26 17:24:45

+2

你确定这是对'malloc'的调用失败吗? “buff_size_n”或“rec_size_n”可能是负值吗?您是否尝试用例如'malloc(sizeof(...)+ ...)'替换'malloc '的malloc(5000)'? – stakx 2010-04-26 17:26:31

+4

c没有例外 – 2010-04-26 17:31:06

回答

8

尝试通过valgrind运行您的程序,查看它报告的内容。在程序的某些其他部分中,可能会损坏空闲列表或malloc查看的其他内容。

+4

+1如果程序在*'malloc'内部发生崩溃*,则几乎可以确保您已将堆损坏到其他地方。 – 2010-04-26 17:39:00

0

你需要做的只是做到这一点。

fl_hdr = malloc(sizeof(fl_hdr_type)); list_pp是void *的一个动态数组,您需要使用另一个malloc将其分配给所需的大小。

list_pp只是一个指向其他堆的指针。

如果你想分配一个malloc,那么你需要将它定义为一个你想要的实际类型的数组。编译器需要知道能够执行分配的类型。

如果你正在寻找的是动态数组在C,then look at this

+0

此外,您需要这样做来缩小问题的原因。 – Puppy 2010-04-26 17:40:42

+0

更新OP与进一步的细节 – Derek 2010-04-26 17:58:56

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 2010-04-26 17:59:21

+0

如果你自己运行这个程序失败? – 2010-04-26 18:07:02

+0

@Derek - 查看我的编辑。 – 2010-04-26 18:30:25

0

你需要明确指定n_plist_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)); 

如果你打算这样做,我建议把指针放在struct结尾,而不是中间。不过,我与Romain合作,并建议您使用单独的电话拨打malloc(),而不是通过一次呼叫抓取所有内容。

+0

在一次调用中分配所有内容有助于减少堆碎片。而且,它更有效率。这些并不是自己的首要原因,但它们在某些情况下可能变得重要。如果你采用单分配方法,你需要确保'* fl_hdr'后面的内存被正确对齐,无论它包含什么。 – 2010-04-26 18:30:45