我有以下结构:
typedef struct binTreeNode
{
void *data;
struct binTreeNode *left;
struct binTreeNode *right;
} myBinaryTreeNode;
在我的main
函数中,我尝试使用指向该结构实例的指针root
。
myBinaryTreeNode *root = malloc(sizeof(myBinaryTreeNode));
printf("\nPlease insert root data: ");
int input;
scanf("%d", &input);
root->data = (void*)&input;
printInt(root->data);
free(root);
此代码运行良好。但是,我认为当你有一个带有成员指针的结构时,你应该free()
每一个(除了指向结构的指针)。
所以在这里,我没有malloc
root->data
(因为我认为结构malloc
会这样做),但它被初始化为输入值并且它& #39; s值成功打印。当我尝试free(root->data)
我的程序崩溃时。
我root->data
时malloc
不是malloc root
?如果没有,我怎么还能使用它?
为什么会这样?我在这里错过了什么?
答案 0 :(得分:3)
首先,了解您需要(或不需要)调用free()
的位置和方式。
对于“ malloc()
,您不需要root->data
”,当您分配的内存等于结构大小时,已经分配了该变量。现在,接下来,你当然需要root->data
指向一些有效的内存,这样你就可以取消引用读取的指针来写入它。你可以通过两种方式之一来做到这一点
malloc()
返回的指针(成功)。如果您存储malloc()
返回的指针,是的,您必须free()
内存,但在您的情况下,root->data
保存malloc()
未返回的指针},所以它不需要free()
- 。
只是添加并强调与free()
相关的部分,必须尝试free()
以前未通过调用分配的内存malloc()
C11
和其他家庭,它会调用undefined behavior。引用,标准void free(void *ptr);
,章节§7.22.3.3,(强调我的)
free
ptr
函数导致ptr
指向的空间被释放,即 可供进一步分配。如果free
是空指针,则不执行任何操作。否则,如果 该参数与先前由内存管理返回的指针不匹配 功能,或者如果通过调用realloc
或{{1}},取消分配空间 行为未定义。
答案 1 :(得分:1)
当我尝试释放(root->数据)时,我的程序崩溃了。
您无法free
内存未动态分配。如果你想要free
元素,你应该先用这种方式分配它们:
typedef struct binTreeNode
{
int *data;
struct binTreeNode *left;
struct binTreeNode *right;
} myBinaryTreeNode;
root->data = malloc(sizeof(int));
if (root->data == NULL)
{
printf("Error allocating memory\n");
return;
}
scanf("%d", root->data);
free(root->data);
请注意,在继续之前,您应该check the result of malloc。
因此,当我使用malloc root时,root->数据不会被malloced?如果没有,我怎么还能使用它?
另请注意,为root->data
分配内存时会分配struct
的空间,但不是malloc
。您需要额外的malloc
,尤其是root->data
,如上例所示。您malloc
需要root->data
的原因是能够取消引用指针。
答案 2 :(得分:1)
input
成员指向typedef struct binTreeNode
{
int *data;
struct binTreeNode *left;
struct binTreeNode *right;
} myBinaryTreeNode;
root->data = malloc(sizeof(int));
scanf("%d", root->data);
free(root->data);
本地变量,因此您无法释放它。
如果您动态分配成员,则必须释放成员,例如
#include <sched.h>
int main ()
{
struct sched_attr attr;
attr.size = sizeof(struct sched_attr);
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 30000000;
attr.sched_period = 100000000;
attr.sched_deadline = attr.sched_period;
if (sched_setattr(gettid(), &attr, 0))
perror("sched_setattr()");
return 0;
}
答案 3 :(得分:1)
我在代码中添加了一些注释。
我希望这能解决问题。
// I have added an enclosing block for the purpose of demonstration:
{
// Here you allocate memory for a tree node object with dynamic/allocated
// storage duration.
// That is: three pointers, that point to nowhere are created and will
// exist until the memory holding them is free'd.
myBinaryTreeNode *root = malloc(sizeof(myBinaryTreeNode));
printf("\nPlease insert root data: ");
// Here you create an object with automatic storage duration.
// That is, the object is automatically destroyed when the function
// returns or the block is closed: { ... }
int input;
// here you attempt to assign a value to the variable
// (you should check the return value: the input may fail)
scanf("%d", &input);
// Here you assign the address of an object to a pointer.
// Note that you are only allowed to use the pointer as long as the
// object it points to "lives".
root->data = (void*)&input;
// Here you probably print the value, or the pointer address, or something else
printInt(root->data);
free(n); // <-- Where and how did you allocate this?
// Here you free the memory holding the tree node
free(root);
} // <-- At this point the "input" variable is automatically destroyed.
您应该真正了解存储持续时间(自动和动态/已分配)以及动态内存分配的目的:
详细解决问题:
当我尝试
free(root->data)
我的程序崩溃时。
这是因为您只能free()
拥有malloc()
。对于不同类型的存储持续时间,内存管理是不同的。
所以当我使用malloc root时,
root->data
没有被malloced?
指针的内存已分配,但它没有&#34;拥有&#34;或者&#34;指向&#34;默认情况下任何对象。
如果没有,我怎么还能使用它?
就像你一样。您为其分配了一个对象的内存地址,它的存在时间足以让您使用它。您可以使用动态内存管理生成此类对象(请注意,一旦完成后手动将其销毁:不要泄漏内存)或使用&#34;自动内存管理&#34;正如你所做的那样(然后注意它不能过早销毁:不要访问无效的内存)。 (仅列举两种创建对象的可能方法......)