【问题标题】:Can't initialize struct with nested pointers to other structs无法使用指向其他结构的嵌套指针初始化结构
【发布时间】:2011-09-30 19:49:41
【问题描述】:

我正在使用定义此结构的第三方库:

typedef struct
{
    unsigned short nbDetectors;
    //! structure of detector status
    struct DetectorStatus
    {
        unsigned int lastError;         //< last detector internal error
        float temperature;              //< detector temperature
        detector_state state;           //< detector state
        unsigned short mode;            //< detector mode

        struct EnergyStatus
        {
            power_source powerSource;           //< front-end power source
            frontend_position frontendPosition; //< front-end position relative to the docking station

            struct BatteryStatus
            {
                bool present;                   //< battery present or not in the detector
                unsigned short charge;          //< charge level of the battery (in %)
                float voltageLevel;             //< battery voltage level
                float temperature;              //< temperature of the battery
                unsigned short chargeCycles;    //< number of charge/discharge cycles
                unsigned short accuracy;        //< Expected accuracy for charge level (in %)
                bool needCalibration;

            } batteryStatus;

        } * energyStatus;

        struct GridStatus
        {
            detector_grid grid;

        } * gridStatus;

    } * detectorStatus;

} HardwareStatus;

该结构被库用作其回调之一传递的数据。所以是图书馆把它填满了,我只是读了它。到目前为止,一切顺利。

但现在我正在为这个库处理的设备编写一个模拟器,所以现在我必须填充其中一个结构,但我无法正确完成。

我试过这个:

HardwareStatus status;
status.detectorStatus->temperature = 20 + rand() % 10;
e.data = &status;
m_pContext->EventCallback( EVT_HARDWARE_STATUS, &e );

当我编译时,我得到:

warning C4700: uninitialized local variable 'status' used

然后我意识到......结构内的指针指向垃圾,很好地抓住了Visual Studio!然后我尝试通过声明最内层结构(BatteryStatus)的实例开始,但这不会编译......因为它不是 typedef'd(它说BatteryStatus 类型未定义)?所以我被难住了......我该如何填充结构?

【问题讨论】:

  • 另外,要设置 batteryStatus,你必须写 EnergyStatus::BatteryStatus s; status.batteryStatus = s; 注意符合条件的 EnergyStatus::...

标签: c++ struct initialization nested


【解决方案1】:

如果你想把所有东西都放在堆栈上,应该这样做:

// Getting structs on the stack initialized to zero
HardwareStatus status = { 0 };
HardwareStatus::DetectorStatus detectorStatus = { 0 };
HardwareStatus::DetectorStatus::EnergyStatus energyStatus = { 0 };
HardwareStatus::DetectorStatus::GridStatus gridStatus = { 0 };

// "Linking" structs
detectorStatus.energyStatus = &energyStatus;
detectorStatus.gridStatus = &gridStatus;
status.detectorStatus = &detectorStatus;

// Now you can fill and use them
status.detectorStatus->temperature = 20 + 3 % 10;
//...

【讨论】:

  • 这可行,但结构初始化中没有零(我仍然无法编辑其他人的帖子)。谢谢!
  • 请注意,如果您打算在完成这些定义的范围之外以这种方式“制作”“状态”变量,则此解决方案可能非常危险。这是因为它在内部指向堆栈上分配的数据,并且该堆栈将消失。我建议你动态分配内存。
  • @Lev: 非常正确,这不是问题,结构体被传递给回调,一旦完成,就不再需要了
  • @dario_ramos:如果这是您的用例,那么一切都很好:) 请确保不要对其进行任何异步操作。
【解决方案2】:

你可以对它进行值初始化:

HardwareStatus status = {};

如果您想实例化 BatteryStatus,您可以通过完全限定名称来实现:

HardwareStatus::DetectorStatus::EnergyStatus::BatteryStatus bs;

【讨论】:

  • 这是一个好的开始,比 memset'ting 为 0 更优雅,但是...我仍然无法触摸 detectorStatus-&gt;temperature,因为 detectorStatus 是无效指针
  • HardwareStatus status = {}; status.detectorStatus-&gt;temperature = 20 + rand() % 10; 这是为我编译的,除了关于 int 到 float 转换的警告。
  • @Gnawme:您的代码通过空指针进行分配。为什么你会期望这行得通?仅仅因为它构建并不意味着它是正确的。
  • @dario:你还没有为detectorStatus 实例化一个DetectorStatus 来指向!
  • @JohnDibling:我同意你的价值初始化;我应该更仔细地阅读 OP 的问题...
【解决方案3】:

您是否尝试过将结构设置为 0 ?

【讨论】:

  • memset(&amp;status, 0, sizeof(status));
  • 好吧,这解决了警告,但现在所有结构的指针都指向 NULL(这里为 0)......所以我仍然无法设置 detectorStatus-&gt;temperature(这实际上是我唯一的想做)
猜你喜欢
  • 1970-01-01
  • 2014-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-14
  • 1970-01-01
相关资源
最近更新 更多