2
votes

I'm building a tiny linked list library for the purposes of self-enrichment, which has forced me to deal with a problem I'm nearly at a loss to explain. Take the following example, and assume that new_item->data is a void pointer inside a typedef struct:

int *data = malloc(sizeof(int));
*data = 42;
MY_LIST *new_item = malloc(sizeof(*new_item));
new_item->data = &data;

// prints what looks like a memory address
printf(
    "data: %i\n",
    *((int *) new_item->data)
);

//prints 42
int data2 = *((int *) new_item->data);
printf(
    "data2: %i\n",
    *((int *) data2)
);

As far as my (probably derelict) brain can tell, in both cases I'm using the same cast statement - *((int *) new_item->data) - to derive the integer from its container. Yet when I use it inline inside of printf, I get a memory address instead. What am I misunderstanding about this?

1
Welcome in the pointer hell. - Max Truxa
adjust your data assignment to new_item->data = data; - amdixon
Shouldn't MY_LIST *new_item = malloc(sizeof(*new_item)); be MY_LIST *new_item = malloc(sizeof(new_item));? sizeof(new_item), not sizeof(*new_item)? - Fiddling Bits
@BitFiddlingCodeMonkey: No, because new_item is a pointer - I want to allocate enough memory for the type which the pointer points to. - Winfield Trail
@sudowned So new_item is a pointer to a pointer to a structure. Got it. Thanks for clearing that up. - Fiddling Bits

1 Answers

2
votes

This is the problem.

new_item->data = &data;

It data is pointing to the address of the pointer (pointer to pointer). data is already a pointer.

Make it following

new_item->data = data;

In the following case

//prints 42
int data2 = *((int *) new_item->data);
printf(
    "data2: %i\n",
    *((int *) data2) //You are dereferencing the pointer,
);

You are dereferencing the pointer that is why it prints 42.

In this case

// prints what looks like a memory address
printf(
    "data: %i\n",
    *((int *) new_item->data)
);

You are dereferncing &data which is stored in new_item->data which is now pointing to data. That is why it is printing an address. To get 42, dereference it again.