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

cigdeys3  于 2022-12-03  发布在  其他
关注(0)|答案(7)|浏览(838)

我有以下结构

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

由于某种原因,实现者选择不将stData作为指针,所以我不得不接受这一点。我的问题是如何检查stData成员是否为空?因为如果它为空,我需要跳过代码中的某些内容。
任何帮助都是感激不尽的

eivgtgni

eivgtgni1#

您需要一些方法来将AnotherStruct stData标记为空。

  • 首先检查(或仔细检查)与AnotherStruct相关的文档和注解,可能的话,询问那些制作它的人,看看是否有一个官方的方法来做你想要的事情。
  • 也许那个结构体有一个指针,如果它是空指针,那么这个结构体就是空的;或者可能有一个整数字段,其中0或-1等可以表示空;或者甚至有一个布尔字段来标记它为空。
  • 如果没有以上任何一项,也许可以添加这样一个字段,或者对某个字段进行这样的解释。
  • 如果上面的方法失败,则向MyData添加一个布尔字段,以判断stData是否为空。
  • 您还可以解释data1和/或data2的某些值(例如,空字符串?充满0xFF字节?),表示空stData
  • 如果你不能修改或重新解释任何一个结构体的内容,那么你可以把空的和非空的项放在不同的容器中(数组,列表,任何你有的容器)。如果MyData项是从堆中一个接一个地分配的,那么本质上这与a free list是一样的。
  • 如果你在一个容器中混合了空项和非空项,那么你可以在另一个容器中包含指向非空项(或者指向空项,或者任何适合你需要的项)的 * 指针 * 或索引。这会带来额外的复杂性,你需要保持两个容器同步,这可能是小事,也可能不是小事。
vxf3dgd4

vxf3dgd42#

您可以找到一些标记变量。

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

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

xuo3flqw3#

我发现我自己和你遇到了类似的问题。我需要打包一个给定的结构,知道结构中的确切字节数将有助于我序列化该结构。然而,一些结构是空的,因此,序列化无法对齐确切的字节数。
虽然这是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;

参考资料如下:

vnjpjtjt

vnjpjtjt4#

如果它不是一个指针,那么当对象MyData被创建时,结构成员的内存将被分配。当你定义你的结构时,用calloc或memset将它们全部设置为零,然后你可以比较0

hts6caw3

hts6caw35#

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

struct x;
int y;

首先尝试回答“在首次声明int后,如何确定它是否为空?”
关于解决方案:-如果你想知道它是否已初始化,请以这种方式使用你的结构:-

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

初始化时将其设置为true。

p1iqtdky

p1iqtdky6#

我假设struct定义是某个第三方功能/库的一部分,其中第三方很可能是您公司内部的某个人。
如果实现者选择不把stData作为指针,那么是有原因的。他们会知道如何表达“stData是空的”,如果它被允许为空的话。你一定要试着在文档中查找那些语义或者和他们交谈。不要试图把你自己的语义添加到一个有特定目的和语义的结构中。
因此,如果有一种预定义的方式来表示结构体的某一部分是空的,那么就使用这种方式。如果对于它的预期用途来说,它可能不是空的,那么就不要试图使它成为空的。简而言之,不要以一种不应该使用的方式来使用类/结构体。相反,如果您发现自己处于只有“MyData”有意义所需的部分数据的情况下,然后编写您自己“MyPartialData”结构来处理这种情况,并在您具备所需的一切并准备好与第三方API交互后将其转换为“MyData”。

pbossiut

pbossiut7#

在我的例子中,我必须检测它是否是NULL伪装成一个结构体。这对我很有效:

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

    return false;
}

结构的地址为nullptr时检测到空值。

相关问题