如何检查结构是否已初始化

时间:2009-11-18 21:01:41

标签: c

typedef struct dict_pair {
  void *key;
  void *value;
  struct dict_pair *head;
  struct dict_pair *tail;
} dict;

dict* NewDictionary(void) {
  dict *dictionary = malloc(sizeof(dict_pair));
  dictionary->head = null;
  dictionary->tail = null;
}

int main(void) {
  dict *dictionary = NewDictionary();
}

我最初计划将结构设置为null,但编译器不允许它。如何检查结构是否已分配?

另外,我可以在结构中以递归方式声明相同的结构吗?

5 个答案:

答案 0 :(得分:8)

C没有null,它有NULL。所以试试这个:

dict* NewDictionary(void) {
  return calloc(sizeof(dict)); 
}

这解决了一些问题:

  1. 您正在离开valuekey未初始化,因此他们可以随机存放垃圾。使用calloc()会将所有内容初始化为0,在指针上下文中为NULL。它甚至不会花费更多的处理时间。
  2. 你没有回来任何东西。这是未定义的行为。如果你的作品在没有return声明的情况下结束,那么只有通过运气才能返回任何内容。
  3. 您使用的是dict_pair而不是struct dict_pair。在C ++中,struct名称在常规类型命名空间中,即t x = { 0 };是有效的C ++,但在C中,您需要说struct t x = { 0 };
  4. 您没有检查malloc()的返回值(现在为calloc(),但适用相同的规则)。如果内存不足,calloc()会返回NULL。我不想在事故中取消引用NULL指针。我们不必在此检查返回值,因为我已经废除了所有中间步骤 - calloc()对我们来说已经足够了。
  5. 请注意,calloc()的可移植性稍差。尽管标准确实要求void *p = 0将指针设置为空指针,但它并不要求空指针“将所有位设置为零”,这在技术上是calloc()。如果由于这个原因你不想使用calloc(),这里有一个与malloc()做同样事情的版本:

    dict* NewDictionary(void) {
      dict *dictionary = malloc(sizeof(dict)); 
      if(dictionary) {
        dictionary->head  = NULL;
        dictionary->tail  = NULL;
        dictionary->value = NULL;
        dictionary->key   = NULL;
      }
      return dictionary;
    }
    

    或者:

    dict* NewDictionary(void) {
      dict *dictionary = malloc(sizeof(dict)); 
      if(dictionary == NULL) return NULL;
      dictionary->head  = NULL;
      dictionary->tail  = NULL;
      dictionary->value = NULL;
      dictionary->key   = NULL;
      return dictionary;
    }
    

    查看calloc()版本有多好?

    至于你的第二个问题:

      

    另外,我可以在结构中以递归方式声明相同的结构吗?

    不,你不能这样做:

    struct t {
      struct t x;
    }
    

    但你可以这样做(这就是你正在做的,你想要的):

    struct t {
      struct t *x;
    }
    

    struct本身内的struct可以有一个指针,但你不能在struct内找到实际的struct本身。你正在做的事情是完全合法的,因为你正在使用指针。

答案 1 :(得分:1)

您可能需要考虑calloc而不是malloc。

calloc用0分配它分配的内存,所以你的头和尾都是NULL,没有显式赋值。

答案 2 :(得分:1)

我将使用静态分配的变量进行初始化:

dict* NewDictionary(void) {
  static dict null_dict; // no initializer, so zero by default
  dict *dictionary = malloc(sizeof *dictionary);
  *dictionary = null_dict;
  return dictionary;
}

这可以保证成员被正确归零,无论它们是指针,浮点还是整数类型。

答案 3 :(得分:0)

您可以将其设为NULL,但不能设为null。 C区分大小写,NULL常量全部为大写。

回答你的第二个问题,是的,struct定义在某种意义上可以是递归的。内部引用必须是指向struct的指针,而不是struct的直接定义。如果后者被允许,你最终会得到一个无限递归的struct定义,这将是一件坏事。有关详细信息,请参阅Chris Lutz的答案。

答案 4 :(得分:0)

我正在使用一种适合我的技巧。

struct hello{
    ....;
    ....;
    ....;
};

struct hello *t;

t=malloc(sizeof(struct hello));
free(t);
t=NULL;

现在,您可以轻松检查t是否已初始化。并且根本没有内存泄漏。