Bitten by an exotic bug

I have been tearing my hair for a couple of evenings not understanding anything about what is happening in my code. It has been very frustrating, but now I think I just understood the whole problem.

It might be obvious, but to me it is very exotic and I am still not sure that I have solved the problem.

So, my problem was this:

I am rewriting the memory handling in the twkb function in PostGIS. Why I am doing that is another story that I will tell when things are working as expected.

I have a structure that looks like this:

typedef struct
{
uint8_t *buf_start;
uint8_t *buf_end;
uint8_t **buf;
} BUFFER_STORAGE; 

Then I wrote a small helper function to do the allocations in this structure.

It looks something like this a little simplified:

int alloc_buffers(BUFFER_STORAGE *buffers, size_t size)
{
uint8_t *bulk;
bulk=(uint8_t*) lwalloc(size); /*a PostGIS-specific allocator function*/
buffers->buf=&bulk;
buffers->buf_start=bulk;
buffers->buf_end=bulk+size;
}

Ok, do you see the problem?
Well, it bites me in a very subtle way. Nothing happens until, when I am back to the calling function, initiates a new variable. Then things go totally wrong. In my struct the buf-pointer goes bananas.

What I just realized is why.

This is what happens (I think):
In my helper function, when I initialize the bulk-variable it is created on the stack. I mean the pointer variable. The bulk itself is allocated on the heap. Then, when I put the address to the local pointer variable in my structure as **buf, I store a local short lived address, in my long living structure. Then, when I get back to the calling function that address is not valid any more, and is reused when I initialize a new variable in the stack.

So, what I saw was that my new variable in the calling function had the same address as I had stored in my structure. When I used my buf-address it just pointed to a pointer to my new variable instead of the bulk I was expecting.

I cannot see any warning telling me that I am doing something stupid.

Does this makes sense, or will I find tomorrow evening that I still haven’t found my problem?