为什么此代码的输出总是相同的

Why is the output of this code always the same?

本文关键字:输出 代码 为什么      更新时间:2023-10-16

为什么我会在C 中的以下循环中获得相同的输出。

node* nn =  (struct node*)malloc(sizeof(struct node));      
for(int i=0;i<10;i++)
{
    node* n =  (struct node*)malloc(sizeof(struct node)); 
    cout<<&n<<endl;
    nn->next = n;
    nn =n;
}

因为您的 n变量是循环主体本地的,因此在每次迭代的开头创建,并在每次迭代的末尾被销毁。

显然,编译器决定为n的每个化身重复使用相同的存储空间,这就是为什么所有人都具有相同的内存地址。

请注意,&nn地址,而不是其内容。您甚至不必初始化它。您对malloc的电话无关。

如果要查看n的值,则需要删除&

您正在输出&n,这是n的地址,而不是n的内容,这可能是您想要的。

nb:问题是在我的回答之后编辑的,但仍然存在同样的问题。

尝试以下操作:

#include <iostream>
#include <cstdlib>
struct node {
    node* next;
};
int main() {
    node* nn =  (struct node*)malloc(sizeof(struct node));      
    nn->next=nullptr;//Initialise so we can clean up nicely...
    for(int i=0;i<10;i++)
    {
        node* n =  (struct node*)malloc(sizeof(struct node)); 
        n->next=nullptr;//Initialise so we can clean up nicely...
        std::cout<<&n<<"=="<<n<<std::endl;
        nn->next = n;
        nn =n;
    }
    //Clean up after ourselves. Not relevant to the question but good practice.
    while(nn!=nullptr){
        node*n=nn;
        free(nn);
        nn=n;
    }
    return 0;
}

典型输出:

0x7ffda1be2058==0x55ffb0b9fc20
0x7ffda1be2058==0x55ffb0ba0c50
0x7ffda1be2058==0x55ffb0ba0c70
0x7ffda1be2058==0x55ffb0ba0c90
0x7ffda1be2058==0x55ffb0ba0cb0
0x7ffda1be2058==0x55ffb0ba0cd0
0x7ffda1be2058==0x55ffb0ba0cf0
0x7ffda1be2058==0x55ffb0ba0d10
0x7ffda1be2058==0x55ffb0ba0d30
0x7ffda1be2058==0x55ffb0ba0d50

实际输出可能会有所不同,原则上不需要编译器将n存储在每个迭代的同一地址中。我知道没有编译器没有。有人吗?

nb:很少建议在C 中使用malloc()malloc()free()的直接替换为newdelete。在实践中,使用std::unique_ptr<>或其他自我管理结构。

这只是梅尔波梅的答案的补充,回答评论:

如何创建n个节点?禁止使用向量,因此我正在创建一个链接的n个节点列表,但是问题是我无法在循环中创建n个节点。

实际上,您的代码比您想象的要不正确,仅仅您错过了一个重要的一点:

nn->next = n;

使用此说明,您失去了对nn最初指向的内容的最后一次引用,并且您将永远无法再次获得它...

您还需要的是第二个指向最初创建的元素的指针,因此您不会丢失列表的头,因此列表的其余部分都不会:

node* nn = new node(); // this is the C++ way...
node* head = nn; // now you have a second pointer to the head... 
for(int i=0;i<10;i++)
/* [...] */

现在您可以访问通过head指针创建的所有节点(只要您不将其移开...(。

摆脱循环,简单地使用struct *n = malloc(sizeof *n *10(; - David C. Rankin

另一个变体:直接创建10个元素...假设节点看起来像这样:

struct node
{
    Data data;
    node* next;
};

然后,您只需

获得10个Data的元素
Data* allData = new Data[10]; // again using the C++ way...

c 的缝隙具有另一个优势:数组中的元素已在调用默认的构造函数时开始初始化(有关原始数据类型,请参见此处(。