声明一个指向结构体的指针会创建一个结构体吗?

3

在我看来,struct new_element *element = malloc(sizeof(*element))创建了一个名为element的结构体,而我原以为它只是创建了一个指向该结构体的指针。下面的代码证明了我的错误:

struct new_element
{
    int i;
    struct new_element *next;
};

int main(void)
{
    struct new_element *element = malloc(sizeof(*element));
    element->i = 5;
    element->next = NULL;
    printf("i = %d, next = %p\n", element->i, element->next);
}

输出:

i = 5, next = (nil);

element->i的值为5,element->next的值为NULL。这难道不意味着element指向了一个结构体,也就是说确实创建了一个结构体吗?我之前认为malloc只会给指针分配所需的内存大小。


3
你的想法是错误的。你对指针、malloc以及其他相关知识存在很大误解。我强烈建议你从好的书籍中学习C语言,而不是通过在线教程或者晦涩的YouTube视频。 - too honest for this site
2
a pointer the size needed”这句话没有意义,数据指针就是数据指针。malloc()返回一个指向你指定大小的可用内存的指针。 - user2371524
2
@nounoursnoir sizeof(element) 给出指针变量所需的空间(与您使用的结构无关),而 sizeof(*element) 则给出所需的结构大小。 - GAURANG VYAS
2
@nounoursnoir 这是一个风格问题,但是 sizeof(struct new_element)sizeof(*element) 将具有相同的值,许多人更喜欢后者的形式,因为它更明确地表示“由 element 指向的对象的大小”。 - Ian Abbott
1
@nounoursnoir 记住,*有不止一种含义。实际上,它有三种含义。根据上下文,它可以是类型的一部分,可以是指针解引用运算符,也可以是乘法运算符。(我在这里没有计算它在注释、字符常量和字符串字面值中的其他用途。) - Ian Abbott
显示剩余16条评论
1个回答

10

变量element是一个指针。当您定义它时,会为该指针分配空间。

如果您只是这样做:


struct new_element *element;

你已经创建了一个指针。但是它目前没有指向任何地方。

当你调用malloc(sizeof(*element))时,它会分配足够大的空间给element所指向的部分,也就是一个struct new_element实例。然后你将变量element指向这段内存。

这段代码:

element->i = 5;

等同于:

(*element).i = 5;

它取消引用指针element,给你一个struct new_element,然后访问成员i

如果您按照评论中所建议的做了这样的操作:

struct new_element *element = malloc(sizeof(element));

你没有正确分配足够的空间。你为一个 struct new_element * 分配了足够的空间,而不是一个 struct new_element。如果该结构体比指向它的指针大(在这种情况下很可能是这样,因为它包含指向自身类型的指针),那么当修改其中一个成员时,就会超出分配内存的末尾。这将导致未定义行为


4
声明语句并不会为变量预留内存空间。而且 C 语言没有栈的概念。 - too honest for this site
@Olaf 是的,应该是“定义”。已修复。 - dbush
2
我已经删除了DV,但仍然不满意添加实现细节。我们真的不应该混合语言和实现。 - too honest for this site
@Olaf 好的,堆栈/堆对于这个特定的问题并不相关。 - dbush
1
@Olaf 你知道一种没有堆栈的C实现吗?也许为了教育目的而谈论堆栈是相关的。 - Boiethios
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接