Keil C51 doesn't allocate memory for struct pointers at compile time

413 Views Asked by At

I'm trying to created a linked list of structs for an EFM8 microcontroller project. I want to have the compiler allocate memory for all of the nodes at compile time. The issue I'm having is that no memory is being allocated for struct pointers.

#define FOO_QUEUE_LEN   32
 
struct Foo {
    uint8_t  bar0;
    struct Foo *next;
};
 
struct Foo queue[FOO_QUEUE_LEN];
 
void main (void)
{
    while(1) { ;; }
}

I would expect this code to allocate 4 bytes for each Foo struct (1 byte for bar0 and 3 bytes for next because in this architecture, if you don't specify memory location a 24-bit address is required.

But when debugging, the structure is reporting back only 1 byte for each struct, and expanding any of the array members shows an Error: cannot dereference this type message.

enter image description here

What's even more strange is that if you operate on the array of structs in the main loop, the size of the struct in memory is calculated correctly: queue[1].bar0 = 0xCC; will write the value to memory address 0x4. The problem being that the compile didn't allocate enough memory so we're overwiting past the bounds of each struct (in this case, 0xCC ends up at queue[4].bar0).

Is there some directive that is needed to size these struct pointers correctly at compile time?

1

There are 1 best solutions below

2
Mike Szczys On

The comment from SergeyA is the correct answer:

I would expect it to be the artifact of the debugger. What happens if you just print the sizeof value?

Consider this expanded version of the program:

#define FOO_QUEUE_LEN   32

struct Foo {
    uint8_t  bar0;
    struct Foo* next;
};

struct Foo xdata queue[FOO_QUEUE_LEN];




void zeroFooStruct(struct Foo *fooPacket) {
    // Using FF for debugging so I can see memory writes
    fooPacket->bar0 = 0xFF;
    fooPacket->next = 0;
}

void initializeFooQueue(void)
{
    uint8_t i;
    struct foo *previous;

    previous = NULL;

    // This linked list is a FILO
    for (i=0; i<FOO_QUEUE_LEN; i++)
    {
        zeroFooStruct(&queue[i]);
        queue[i].next = previous;
        previous = &queue[i];
    }
}

void main (void)
{
    uint16_t s;
    uint16_t mydata = 0xCCCC;
    initializeFooQueue();

    s = sizeof(queue);

    while(1) { ;; }
}

We can see that for each node we're storing 0xFF for bar0 and the address to the previous node. 4 bytes times 32 nodes = 0x80 memory slots. That memory space then has our expected sizeof value (0x0080) followed by our dummy value (0xCCCC), showing that there is indeed a correct amount of memory allocated and it's the debugger that's not displaying the memory correctly.

enter image description here