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,但编译器不允许它。如何检查结构是否已分配?
另外,我可以在结构中以递归方式声明相同的结构吗?
答案 0 :(得分:8)
C没有null
,它有NULL
。所以试试这个:
dict* NewDictionary(void) {
return calloc(sizeof(dict));
}
这解决了一些问题:
value
和key
未初始化,因此他们可以随机存放垃圾。使用calloc()
会将所有内容初始化为0,在指针上下文中为NULL
。它甚至不会花费更多的处理时间。return
声明的情况下结束,那么只有通过运气才能返回任何内容。dict_pair
而不是struct dict_pair
。在C ++中,struct
名称在常规类型命名空间中,即t x = { 0 };
是有效的C ++,但在C中,您需要说struct t x = { 0 };
。malloc()
的返回值(现在为calloc()
,但适用相同的规则)。如果内存不足,calloc()
会返回NULL
。我不想在事故中取消引用NULL
指针。我们不必在此检查返回值,因为我已经废除了所有中间步骤 - calloc()
对我们来说已经足够了。请注意,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
是否已初始化。并且根本没有内存泄漏。