views:

257

answers:

4

Hi all,

I have a structure defined like so:

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

and in my code I Have a function for initlialization that has the following

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

where those buffer size are passed in to the function to allow space for the buffers as well.

The size is pretty small typically..100*50 or something like that..plenty of memory on this system to allocate it. I can't actually post the stack trace because this code is on another network, but some information pulled from dbx on the core file:

buff_size_n = 32, rec_size_n = 186

and the stack..line numbers from malloc.c

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

Any ideas why this fails?

+8  A: 

Try running your program through valgrind, see what it reports. It's possible in some other part of the program you have corrupted free lists or something else malloc looks at.

frankc
+1 If the program is crashing *inside* `malloc`, it is virtually guaranteed that you have corrupted the heap somewhere else.
Tyler McHenry
A: 

What you need to do is simply do this.

fl_hdr = malloc(sizeof(fl_hdr_type)); The list_pp is a dynamic array of void* and you need to allocate that to the size you need with another malloc.

list_pp is simply a pointer to something else that is allocated on then heap.

If you want to allocate in place with one malloc, then you will need to define it as an array of the actual types you want. The compiler needs to know the types to be able to perform the allocation.

If what you are looking for is dynamic arrays in C, then look at this.

Romain Hippeau
Additionally, you need to do that to narrow down the cause of the problem.
DeadMG
updated OP with further details
Derek
A: 

I made your example into a program, and have absolutely no issues running it. If you can compile and run this simple code (and it works), you have corrupted the heap somewhere else in your program. Please run it through Valgrind (edit as User275455 suggested, I did not notice the reply) and update your question with the output that it gives you.

Edit

Additionally, please update your question to indicate exactly what you are doing with **list_pp and *n_p after allocating the structure. If you don't have access to valgrind, at least paste the entire trace that glibc printed when the program crashed.

#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;
}
Tim Post
Updated the OP with what details i can get from the core file, but we do not have valgrind on that system..will have to look into that soon
Derek
And if you run this program by itself it fails ?
Romain Hippeau
@Derek - see my edits.
Tim Post
A: 

You need to explicitly assign n_p and list_pp to the appropriate offsets.

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

If you're going to do this, I'd recommend putting the pointers at the end of the struct, instead of the middle. I'm with Romain, though, and recommend you use separate calls to malloc() instead of grabbing everything with one call.

TMN
Allocating everything in one call helps reduce heap fragmentation. Also, it's somewhat more efficient. These aren't overriding reasons by themselves, but they can become important in some contexts. If you do adopt the single-allocation approach, you need to be sure that the memory immediately after `*fl_hdr` is properly aligned for whatever it contains.
Dale Hagglund