Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c - properly allocate memory for a struct containing an array of another struct

Tags:

c

memory

I want to allocate memory for a struct that contains an array of another struct named table. I detected that when assigning the pointers to the functions at the end, the variables in the linkedObjects array get corrupted so i think my handling of dynamic memory is wrong.

This is how i'm doing it now:

typedef struct Object {
    void *key;
    struct Object *top;
    struct Object *next;
} Object;

typedef struct Table{
    Object *linkedObjects;
    size_t size, originalSize;
    HashFcn hfun;
    PrintFcn pfun;
    ComparisonFcn fcomp;
} Table;

TableP CreateTable(size_t tableSize, HashFcn hfun, PrintFcn pfun, ComparisonFcn fcomp)
{
    int i;
    struct Table *table = malloc(sizeof(table));
    if (table==NULL)
    {
        ReportError(MEM_OUT);
        return NULL;
    }
    table->linkedObjects = NULL;
    table->linkedObjects  = malloc(tableSize * sizeof(Object));

    for(i=0;i<tableSize;i++)
    {

        table->linkedObjects[i].next = malloc( MAX_IN_LIST*sizeof(Object) );
        table->linkedObjects[i].top = malloc( MAX_IN_LIST*sizeof(Object) );
        table->linkedObjects[i].key = NULL;
        table->linkedObjects[i].top->key = NULL;
        table->linkedObjects[i].next->key = NULL;

        if (table->linkedObjects[i].next == NULL)
        {
            ReportError(MEM_OUT);
            return NULL;
        }
    }

    table->size = tableSize;
    table->originalSize = tableSize;
    table->hfun = hfun;
    table->pfun = pfun;
    table->fcomp = fcomp;
    return table;
}

Edit: I edited the function code to reflect the answers:

TableP CreateTable(size_t tableSize, HashFcn hfun, PrintFcn pfun, ComparisonFcn fcomp)
{
    int i;
    struct Table *table = malloc(sizeof(table));
    if (table==NULL)
    {
        ReportError(MEM_OUT);
        return NULL;
    }
    table->linkedObjects = NULL;
    table->linkedObjects  = malloc(tableSize * sizeof(Object));

    if (table->linkedObjects == NULL)
    {
        ReportError(MEM_OUT);
        return NULL;
    }

    for(i=0;i<tableSize;i++)
    {
        table->linkedObjects[i].next = NULL;
        table->linkedObjects[i].top = NULL;
        table->linkedObjects[i].key = NULL;
    }

    table->size = tableSize;
    table->originalSize = tableSize;
    table->hfun = hfun;
    table->pfun = pfun;
    table->fcomp = fcomp;
    //printf("%p\n", table->hfun);
    return table;
}

but still when i get to the point of the assignments at the end, the table->linkedObjects[0].key that is null and value is 0x0 get's overrun to a value 0x8048cc0. This occurs when this line is executed:

table->originalSize = tableSize;

Another Edit: Confirmed that it happens randomly in the last calls (not only in the line above):

table->size = tableSize;
table->originalSize = tableSize;
table->hfun = hfun;
table->pfun = pfun;
table->fcomp = fcomp;
like image 272
Tom Avatar asked Dec 25 '12 17:12

Tom


People also ask

How do you allocate memory for an array of structs?

The memory can be allocated using the malloc() function for an array of struct . This is called dynamic memory allocation. The malloc() (memory allocation) function is used to dynamically allocate a single block of memory with the specified size. This function returns a pointer of type void .

How is struct memory allocated C?

If we create an object of some structure, then the compiler allocates contiguous memory for the data members of the structure. The size of allocated memory is at least the sum of sizes of all data members. The compiler can use padding and in that case there will be unused space created between two data members.

Will memory be allocated for a structure if declare a structure pointer?

Yes memory is allocated to *S1 only when you explicitly allocate. As opposed to S2 which is an actual struct ,not a pointer.

Can we dynamically allocate memory for structure in C?

The “malloc” or “memory allocation” method in C is used to dynamically allocate a single large block of memory with the specified size. It returns a pointer of type void which can be cast into a pointer of any form.


1 Answers

struct Table *table = malloc(sizeof(table));

should be

struct Table *table = malloc(sizeof(Table));

I sometimes love C.

`

like image 196
n. 1.8e9-where's-my-share m. Avatar answered Oct 17 '22 17:10

n. 1.8e9-where's-my-share m.