Malloc 与创建数据结构
Posted
技术标签:
【中文标题】Malloc 与创建数据结构【英文标题】:Malloc vs Creating a Data Structure 【发布时间】:2021-11-22 07:24:48 【问题描述】:malloc 有什么用,而不仅仅是在 c 函数中创建结构?例如,这是在二叉搜索树中创建节点的模型代码。
void insertBSTNode(BTNode **node, int value)
if (*node==NULL)
*node=malloc(sizeof(BTNode));
(*node)->item =value;
(*node)->left =NULL;
(*node)->right = NULL;
return;
if ((*node)->item > value)
insertBSTNode(&((*node)->left), value);
else if ((*node)->item <value)
insertBSTNode(&((*node)->right), value);
else
printf("Already exists in the BST\n");
return;
return;
我尝试做类似的事情,但改为像这样创建结构:
void insertBSTNode(BTNode **node, int value)
if ((*node) == NULL)
BTNode insert;
insert.item = value;
insert.left = NULL;
insert.right = NULL;
(*node) = &insert;
return;
else
int Nodeitem = (*node)->item;
if (value>Nodeitem)
insertBSTNode(&((*node)->right),value);
return;
if (value<Nodeitem)
insertBSTNode(&((*node)->left),value);
return;
但 Nodeitem 将始终是地址。为什么 malloc 在这种情况下工作?当我使用
BTNode insert
,这与使用 malloc 而不是 &insert
只是指向内存位置不同吗?那我应该改用 malloc 吗?
【问题讨论】:
您的第二个版本创建了悬空指针,因此您的代码将调用 未定义的行为(并且通常会做一些奇怪的事情) 我可以知道为什么它会创建悬空指针吗?我应该怎么做才能更正第二个版本。 在您的代码中,insert
是一个自动变量(在块或函数中定义,而不是静态的)。它将在定义它的 bloc 结束时达到其生命周期的终点,并且任何指向它的指针都将在此之后被称为 dangling。因为在对象达到其生命周期结束后尝试使用它显然是未定义的行为。
感谢您的帮助!我假设(非常错误地)记忆在某种程度上比函数中的变量更永久。
【参考方案1】:
当使用BTNode insert;
时,您正在使用堆栈中的内存。只要您只在insertBSTNode
函数内处理这些数据,这很好,但是一旦您离开该函数,堆栈内存就可以(并且将)被其他函数使用。另一方面,malloc
使用堆内存,因此您可以在调用 malloc
的函数之外使用分配的内存,而不会有被其他函数覆盖的风险。您还必须记住,使用 malloc
分配的内存必须在您的应用程序不再需要时手动释放。
【讨论】:
“你正在使用堆栈中的内存”:这个说法大部分时间是正确的,但在 C 语言中正式没有堆栈。语句应该是 "BTNode insert;
声明了一个局部变量,该变量将在程序离开作用域后立即结束。"
@Jabberwocky,您是正确的,因为 c 标准不要求使用堆栈内存实现局部变量。但也有可能争辩说,具有自动存储的变量的 lifo 特性使它们根据定义成为堆栈。因此,我会说 “你正在使用堆栈中的内存” 是一个很好的心理模型,即使在技术上可能不正确。以上是关于Malloc 与创建数据结构的主要内容,如果未能解决你的问题,请参考以下文章