来自结构的函数中的指针不起作用

Pointer in Function from a Struct not working

假设我有一个这样的结构:

 typedef struct myInfo {
    WORD myCount;
    WORD data[0];
} myInfo;

好吧,我想在另一个 .c 源文件中使用这个结构(顺便声明为 extern),其中我有这样一个函数:

void dynamic_init(struct myInfo dummy){ 

     macroPut(5, dummy.myCount, &dummy.mydata); <- doesn't work
      macroPut(5, dummy.myCount, &externalInitialized.mydata); <- works
}

这样我就可以动态地使用这个 dynamic_init 而不必担心结构名称... 但是正如您在上面的代码片段中很容易看到的那样,它仅适用于初始化结构......但是如果我这样调用函数:

 dynamic_init(externalInitialized); 

不行。

换句话说,我必须做这样的事情:

 dynamic_init( externalInitialized.myCount, externalInitialized.mydata);

我得到了预期的结果。

主要的谜团是 "mydata" WORD 破坏了一切。 如果我这样做,"myCount" 会按预期工作:

   dynamic_init( externalInitialized, externalInitialized.mydata);

然后:

void dynamic_init(struct externalInitialized dummy, WORD *dynData){

  macroPut( 5, dummy.myCount, &dynData); <- works

}

我知道这很蠢,但它只是为了显示确切的错误部分。

谢谢!

当您将结构传递给函数时,编译器会生成代码来复制结构内容,因此函数会获得自己的参数副本,可以在不影响原始参数的情况下自由修改。复制执行 sizeof struct 个字节。

你这里的主要问题是你的结构有 flexible array member,所以它的 sizeof 与它实际占用的大小关系不大。

例如有问题的结构 sizeof 是 4(最后一个字段是 0 元素的数组,所以它不会增加 sizeof),但是当你为结构分配内存时,你实际上分配了更多 - 并节省了 'real' 大小结构域。这样,访问 data 数组实际上将获取结构本身之外的元素(放置在它的下一个字节的右边);然而,编译器并不知道(也无法知道,因为一个结构实例的大小与另一个结构实例不同)。出于同样的原因,您不能直接将该结构放在堆栈上并安全地填充数据 - 因为这会触及不属于它的字节并破坏其他东西(从技术上讲,它可以放在堆栈上,但您必须在其中手动对齐它足够大小的堆栈数组)。

灵活的数组成员有其他限制,比如你不能创建这种类型结构的数组(再一次 - 技术上你可以,但它没有意义,因为数组索引依赖于 sizeof)。

所以,简短的回答是 "don't pass flexible-sized structures by value"。或者甚至在按值传递结构之前三思而后行 - 毕竟复制不是免费的。