【问题标题】:Finding the address of nested structure member variables查找嵌套结构成员变量的地址
【发布时间】:2016-08-11 10:25:53
【问题描述】:

亲爱的stackoverflow爱好者,

首先我是stackoverflow的新手,所以对于我犯的任何错误,我提前道歉。

这是一种 C 拼图。或者至少我对此感到困惑。代码如下。

struct outer_str
{
  struct nest_str1
  {
     int mem1;
  };
  struct nest_str2
  {
     int mem2;
  }nest_var2;
}outer_var;

int main()
{
   outer_var.nest_var2.mem2 = 111;
   printf("\n\nThe value of mem2 is %d\n\n",outer_var.nest_var2.mem2);

   // Statement to assign mem1 of nest_str1 with a value say 333;
   // Statement to print the value of mem1 of nest_str1;

   return 0;
}

根据 cmets 的建议,您必须访问嵌套结构 nest_str1 的成员变量 mem1。另请注意,没有为嵌套结构nest_str1 声明结构变量。

希望我尝试了以下代码,模仿了一点 C++。

outer_var.nest_str1.mem1=333;

当我使用 GCC 4.6.3 编译程序时,显示以下错误

"struct outer_str has no member named 'nest_str1' ".

然后我想从嵌套结构nest_str2的结构变量nest_var2的地址找到nest_str1的地址。我尝试了以下代码,

int main()
{
 int offset;
 struct nest_str1 * addr; 
 offset=sizeof(int); // There is only one integer mem1 in nest_str1
 addr=(struct nest_str1 *)((int *) & (outer_var.nest_var2) - offset);
 addr->mem1=333;
 printf("\n\nThe value of mem1 is %d\n\n",addr->mem1);
 return 0;
}

程序编译成功。但是输出不是我所期望的。我遇到了运行时错误。

Segmentation fault (core dumped)

现在我什至不知道我的方法是否正确。所以希望大家给点建议。我也担心我可能忽略了一些明显简单的解决方案。

我也想知道我们是否可以在下面给出的代码中访问mem1

struct outer_str
{

  struct nest_str1
  {
     int mem1;
  };

}outer_var;

我提前感谢每一个人的时间和耐心。

【问题讨论】:

  • 有些人需要注意这一点,因为上面的语法被一些编译器接受。他们会认为 nest_str1 是该结构的匿名(或未命名)成员,并允许“直接”访问 成员,如:outer_var.mem1 = 7; 可以正常编译。但它绝对不便携! (添加此内容仅供参考,因为有些人可以侥幸逃脱,有些人则不能——而且这里有很多读者......)
  • @SteveValliere,如果结构是匿名的,即未按上述方式命名,就会出现这种情况。 (struct { int mem1; };) AFAIK
  • @Nim 结构 tag 的存在不会影响结构的 instance 是否是匿名的。你可以命名一个没有标签的结构实例,然后你不能在其他任何地方重用结构定义(因为它是匿名的。)这可能不清楚,抱歉。这就是为什么我认为值得一提的是,通常应尽可能避免匿名成员——它们令人困惑且不可移植。
  • @SteveValliere 不确定它在 C++ 中的情况,但在 C 中,“类型说明符是结构说明符 没有标签 的未命名成员称为 匿名结构;类型说明符是联合说明符没有标记的未命名成员称为匿名联合。" (我强调的粗体部分,原文为斜体。)
  • @DanielFischer 我的大部分工作都使用 MSVC,并从随附的文档中获得了我的条款。例如 msdn.microsoft.com/en-us/library/z2cx9y4f.aspx> 第一行说 “Microsoft C 扩展允许您在另一个结构中声明结构变量而无需为其命名。这些嵌套结构称为匿名结构。C++ 不允许匿名结构。 " 我可以肯定地说,它也适用于他们的普通 C 编译器——我们编写和维护的近 1,000,000 行代码中的任何一个都不使用 C++。

标签: c


【解决方案1】:

outer_var 中没有任何成员可以让您访问mem1(您还没有声明一个成员,您只是定义了一个名为nest_str1类型。)

将其更改为:

struct outer_str
{

  struct nest_str1
  {
     int mem1;
  } nest_var1;  // now there is a member!

}outer_var;

现在你可以:

outer_var.nest_var1.mem1 = 100;

您的尝试完全是错误的,mem1 没有存储空间,因此即使您的代码有效,您也很可能最终会写入 mem2 的位置。

【讨论】:

  • 谢谢。但是当结构outer_str的结构变量outer_var被创建时会发生什么呢?
  • 但是我已经从mem2的地址中减去了offset。
  • 因此段错误,你正在写入一些随机内存位置,正如我所说,mem1 没有 storage,默认情况下 gcc 不会处理你的第一个结构作为一个 anonymous 结构(您已将其命名,因此,它被视为 type)。去掉名字,然后mem1就可以从outer_var访问为outer_var.mem1)
  • 现在当我将代码更改如下时,它没有显示任何错误。 addr=(struct nest_str1 *)((char *) & (outer_var.nest_var2) - offset);现在我不知道数据存储在哪里。
  • 但是你为什么要这样做呢?如果nest_str1被视为匿名结构成员,你应该可以直接访问mem1为-outer_var.mem1 = 333,如果你不能mem1outer_str的布局中不存在,所以你做什么将调用未定义的行为。
【解决方案2】:

你写的代码是绝对正确的。但是,在从第二个嵌套结构“outer_var.nest_var2”中减去“偏移”值时,尽管将其类型转换为 (int ),但只需将其类型转换为 (char),即“addr=(struct nest_str1 *) ((char *) & (outer_var.nest_var2) - (char *)offset);"并且您将能够在第一个结构中填充变量。

#include<stdio.h>
#include<stdlib.h>

struct outer_str{
        struct nest_str1
  {
     int mem1;
  };
  struct nest_str2
  {
     int mem2;
  }nest_var2;
}outer_var;

int main()
{
    int offset;
    struct nest_str1 * addr;
    offset=sizeof(int); // There is only one integer mem1 in nest_str1
    addr=(struct nest_str1 *)((char *) & (outer_var.nest_var2) - (char          *)offset);
    addr->mem1=333;
    printf("\n\nThe value of mem1 is %d\n\n",addr->mem1);
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-23
    • 1970-01-01
    • 2018-12-08
    • 1970-01-01
    相关资源
    最近更新 更多