OHHH
OHHH

Reputation: 1051

Why doesn't malloc allocate memory at all?

I have the following struct:

struct block {
    void *addr; /*start address of memory for this block */
    int size;
    struct block *next;
};

I have the following code to initialize each block:

void block_init(struct block *b, void *addr, int size){

    /*Allocate space and fill b with the initial data.*/
    b = (struct block *)malloc(sizeof(struct block));
    if(b){
        b->addr = addr;
        b->size = size;
        b->next = NULL; 
    }    
}

I am calling the following lines from another function:

struct block *list;
block_init(freelist, mem, size);

However, it never initializes the block.

I used gdb to test this, however everytime I get a NULL pointer:

123     b = (struct block *)malloc(sizeof(struct block);
(gdb) next
124     if(b){
(gdb) print b
$2 = (struct block *) 0x0
(gdb) print b->size
Cannot access memory at address 0x8

I don't know what's going on, can someone help me out?

Upvotes: 1

Views: 384

Answers (2)

Norman Gray
Norman Gray

Reputation: 12514

Without disagreeing with what @pranit-kothari said, a possibly more idiomatic way of writing the original function is

struct block* block_init(void *addr, int size) {
    /*Allocate space and fill b with the initial data.*/
    struct block* b = (struct block *)malloc(sizeof(struct block));
    if (b) {
        b->addr = addr;
        b->size = size;
        b->next = NULL; 
    }
    return b;
}

That avoids modifying any arguments (which I usually feel is a 'code smell'), is rather clearer to read, and is probably tidier to call.

(Just by the way, was the malloc argument supposed to be size * sizeof(struct block)?)

Upvotes: 1

Pranit Kothari
Pranit Kothari

Reputation: 9841

You have used block *, so if you change value of b, it will not reflect to calling function. You should use block**.

void block_init(struct block **b /*HERE*/, void *addr, int size){

    /*Allocate space and fill b with the initial data.*/
    *b /*AND HERE*/ = (struct block *)malloc(sizeof(struct block));
    if(*b){
        (*b)->addr = addr;
        (*b)->size = size;
        (*b)->next = NULL; 
    }    
}

Call Function,

block_init(&list , mem, size);//pass by address

Upvotes: 4

Related Questions