2

我正在尝试为 EFM8 微控制器项目创建一个结构链接列表。我想让编译器在编译时为所有节点分配内存。我遇到的问题是没有为结构指针分配内存。

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

我希望这段代码为每个Foo结构分配 4 个字节(1 个字节bar0和 3 个字节,next因为在这种架构中,如果您不指定内存位置,则需要 24 位地址。

但是在调试时,该结构只报告每个结构的 1 个字节,并且扩展任何数组成员都会显示一条Error: cannot dereference this type消息。

在此处输入图像描述

更奇怪的是,如果在主循环中对结构体数组进行操作,结构体在内存中的大小计算正确:queue[1].bar0 = 0xCC;会将值写入内存地址0x4。问题是编译没有分配足够的内存,所以我们超出了每个结构的边界(在这种情况下,0xCC结束于queue[4].bar0)。

在编译时是否需要一些指令来正确调整这些结构指针的大小?

4

1 回答 1

2

SergeyA的评论是正确的答案:

我希望它是调试器的工件。如果只打印 sizeof 值会发生什么?

考虑这个程序的扩展版本:

#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) { ;; }
}

我们可以看到,对于每个节点,我们为 bar0 存储 0xFF 和前一个节点的地址。4 个字节乘以 32 个节点 = 0x80 个内存插槽。然后,该内存空间具有我们的预期sizeof值(0x0080),后跟我们的虚拟值(0xCCCC),表明确实分配了正确的内存量,并且调试器没有正确显示内存。

在此处输入图像描述

于 2021-08-02T18:47:25.300 回答