如何在 C 或 C++ 中检查结构是否为 NULL

问题描述 投票:0回答:8

我有以下结构

typedef struct 
{
   char      data1[10];
   char      data2[10];
   AnotherStruct  stData;
}MyData;

出于某种原因,实现者选择不将 stData 作为指针,所以我必须忍受这一点。 我的问题是如何检查 stData 成员是否为空?因为如果它是空的,我需要跳过代码中的某些内容。

如有任何帮助,我们将不胜感激

c++ c data-structures
8个回答
17
投票

您需要某种方法将

AnotherStruct stData
标记为空。

  • 首先检查(或仔细检查)与

    AnotherStruct
    相关的文档和注释,可能会询问那些制作它的人是否有空,以了解是否有官方方法可以完成您想要的操作。

  • 也许该结构体有一个指针,如果它是空指针,则该结构体为空。或者也许有一个整数字段,其中 0 或 -1 或其他值可能表示空。或者甚至是一个布尔字段将其标记为空。

  • 如果以上都没有,也许你可以添加这样一个字段,或者对某个字段的这样的解释。

  • 如果上述失败,请向

    MyData
    添加一个布尔字段以判断
    stData
    是否为空。

  • 您还可以解释

    data1
    和/或
    data2
    的某些值(例如,空字符串?充满 0xFF 字节?),表示空
    stData

  • 如果您无法修改或重新解释任一结构的内容,那么您可以将空和非空项目放入不同的容器中(数组、列表,无论您拥有什么)。如果

    MyData
    项是从堆中逐一分配的,那么这本质上与拥有 空闲列表相同。

  • 上述的变体,如果您将空和非空项目全部混合在一个容器中,那么您可以使用另一个容器,其中带有指针或指向非空项目(或空项目,或其他任何内容)的索引适合您的需要)。这有额外的复杂性,您需要保持两个容器同步,这可能很重要,也可能不那么简单。


4
投票

我发现自己也遇到了和你类似的问题。我需要对给定的结构进行打包,并且了解结构中的确切字节数将有助于我序列化该结构。但是,某些结构是空的,因此序列化无法对齐确切的字节数。

虽然已经过去了 3 年,但我发现了以下对我有用的解决方案:

template <typename T> struct is_empty {
    struct _checker: public T { uint8_t dummy; };
    static bool const value = sizeof(_checker) == sizeof(T);
};

结果可以通过

is_empty<T>::value
查询,并且在编译时可用。

template <typename S>
typedef union {
    struct __attribute__((__packed__)) {
        ObjId   id;
        S       obj;
    } dataStruct;
    std::array<uint8_t, (sizeof(dataStruct) - is_empty<S>::value)> byteArray;
} _msg_t;

参考资料如下:


3
投票

你可以找到一些标志变量。例如。

struct AnotherStruct {
    bool valid;
    char aother_data1[10];
    char aother_data1[10];
    //...
};

if (stData.valid==true){
    //do something
}

1
投票

如果它不是指针,则在创建对象 MyData 时将分配结构成员的内存。当您定义结构时,使用 calloc 或 memset 将它们全部设置为零,然后您可以与 0 进行比较


0
投票

Struct 是用户定义的类型,因为 int 是内置类型。

struct x;
int y;

首先尝试回答“在第一次声明之后如何确定你的 int 是否为空”

关于解决方案:- 如果您想知道它是否已初始化,请以这种方式使用您的结构:-

struct X
{
  bool b;
  X() : b(false) {}  
};

初始化时设置为true。


0
投票

我假设结构定义是某些第三方功能/库的一部分,其中第三方很可能是您自己公司内部的人员。

如果实现者选择不将

stData
作为指针,那么是有原因的。他们将知道如何表达“
stData
是空的”,如果甚至允许它为空的话。您绝对应该尝试在文档中查找这些语义或与他们交谈。不要尝试将您自己的语义添加到具有特定目的和语义的结构中。

因此,如果存在预定义的方式来表示结构体的该部分为空,请使用该方式。如果它对于其预期用途来说可能不为空,那么不要尝试将其设为空。简而言之,不要以不应该使用的方式使用类/结构。相反,如果您发现自己只拥有“MyData”有意义的部分数据,则可以编写自己的“MyPartialData”结构来处理这种情况并将其转换为“MyData”一旦您拥有所需的一切并准备好与第三方 API 交互。


0
投票

就我而言,我必须检测它是否是伪装成结构的 NULL。 这对我有用:

bool IsThisNull(PayloadParamBase& p)
{
    if (&p == nullptr)
        return true;

    return false;
}

通过结构体地址为 nullptr 检测到 Nullity。


0
投票

我发现的方法是,将结构体作为 nullptr 指针启动:

MyData *mydata = nullptr;

然后对其进行评估,如下所示:

if(mydata != nullptr)
{
}

请注意,如果您尝试从 auto 类型的变量进行计算,则必须执行以下操作:

for(auto object : objectList)
{
    auto nullValue = nullptr;
    if(object->mydata != nullValue)
    {
    }
}

不要忘记始终将结构初始化为 nullptr。

© www.soinside.com 2019 - 2024. All rights reserved.