在C中取消引用malloc()的返回

时间:2014-01-17 14:12:06

标签: c pointers malloc dereference

我需要为结构指针数组分配内存。 malloc()的文档通知此函数的返回返回指向已分配的第一个内存块的指针。好吧,在我的情况下,我调用了这样的函数:

malloc(SIZE_TABLE*sizeof(struct structName*))

问题在于,由于malloc返回指向此内存(包含指针)的指针,因此它将返回类型为structName的2星指针。

您可以取消引用呼叫本身,而不是使用额外的行来分配2星指针然后取消引用它吗?

而不是:

struct structName** temp = malloc(SIZE_TABLE*sizeof(struct structName*))

struct structName* temp2 = *(temp);

你可以这样做:

struct structName* temp2 = *( malloc(SIZE_TABLE*sizeof(struct structName*)) );

关于二星指针我做的很少,所以如果有更好的方法来解决这个问题(或者如果我只是错过了解它),请告诉我。

4 个答案:

答案 0 :(得分:5)

不,你不能直接这样做。

malloc返回void*取消引用void*未定义,它会生成编译器警告。
但是您可以将其转换为不同的指针类型然后取消引用 以下可能有效:

struct structName* temp2 = *((struct structName**)malloc(SIZE_TABLE*sizeof(struct structName*)));

但这是一个严重的内存泄漏,因为malloc的原始返回值已丢失且根本不是好习惯,因为您不确定malloc的返回值。如果NULL无法解除引用。

这样做还有另一个问题。 malloc返回的地址处的值未初始化,因此在转换后取消引用它也会导致未定义的行为。

在取消引用任何指针之前,请务必检查NULL
以后始终将malloc的返回值保存到free

答案 1 :(得分:3)

你不能。这是因为malloc的返回值为void *,并且不知道在这种情况下此void *转换为哪种类型。取消引用void *会调用未定义的行为

如果你这样做,你也会在大多数编译器中收到警告,例如为GCC

warning: dereferencing ‘void *’ pointer [enabled by default]    

I would not suggest you to cast the return value of malloc然后取消引用它。最好坚持第一种方法。

答案 2 :(得分:2)

正如其他人所说,如果你添加一个类型转换,你可以取消引用它。但你不应该。已经提到的一个原因是检查NULL。另一个是:

  • 总是必须保存malloc返回的指针,以便以后能够释放内存。

答案 3 :(得分:1)

您需要记住,您的malloc将SIZE_TABLE指针分配给struct structName,但未分配这些struct structName。更糟糕的是:malloc分配的缓冲区未初始化,因此没有一个指针被初始化/有效。

您需要做什么:

struct structName ** table = malloc(SIZE_TABLE*sizeof(struct structName*));
size_t i;
for(i = 0; i < SIZE_TABLE; ++i)
    table[i] = malloc(sizeof(struct structName));

你的建议:

struct structName * tableEntryAtIndex0 = malloc(SIZE_TABLE*sizeof(struct structName*));

这不能编译,你不能取消引用void *

这两行中的任何一行都会编译:

// Either the way you wanted it
struct structName * tableEntryAtIndex0 = *((struct structName **)malloc(SIZE_TABLE*sizeof(struct structName*)));
// Or with an index to punctuate that a table was malloc-ed (in my opinion better to understand what happens)
struct structName * tableEntryAtIndex0 = ((struct structName **)malloc(SIZE_TABLE*sizeof(struct structName*)))[0];

这仍然有两个问题:首先你丢失了指向整个表的指针。所以你不能检查它是否为NULL,你不能访问任何其他表项,你不能释放内存。其次,表没有被malloc初始化,所以你得到一个垃圾指针。现在将tableEntryAtIndex0设置为malloc(sizeof(struct structName))无济于事,因为这只会修改tableEntryAtIndex0而不是表中的条目。