我编写了以下玩具程序并观察到第二个变量 test2 将采用第一个变量 test1 释放的内存地址。即使我自由(test1),test2也会保留test1的字段值。我想知道如何清理C中的free()留下的数据:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct test_str
{
char name[128];
int Id;
} test_str;
typedef test_str* mytest;
int main()
{
mytest test1 = malloc(sizeof(test_str));
printf("test1 pointer address is %p \n", test1);
strcpy(test1->name, "hello world");
test1->Id = 10;
free(test1);
// test1->name = NULL; /* this does not work */
// test1->Id = 0; /* without resetting Id = 0, test2->Id will show 10 */
test1 = NULL;
mytest test2 = malloc(sizeof(test_str));
printf("test2 pointer address is %p, name field is %s, Id = %d \n", test2, test2->name, test2->Id);
return 0;
}
这是输出:
test1指针地址为0x2401010
test2指针地址为0x2401010,名称字段为hello world,Id = 10
答案 0 :(得分:3)
如果您的数据非常敏感,请使用平台调用来固定内存,并使用对某些memset
- 变体的非线性调用,以便在免费之前清除。
当您将内存返回给运行时时,可以将其用于下一个拟合请求。它是否以及何时这样做,或者是否将内存恢复到可能的操作系统,并不是标准规定的。
除此之外:void free(void*) {}
是free
的有效实现。
答案 1 :(得分:2)
地球上几乎没有任何理由可以做到这一点......
然而,在test1->name[0]=0
之前添加free(test1)
应该可以胜任。
如果你想删除&#34;所有追踪&#34;在上一篇文章中,您甚至可以这样做:
for (int i=0; test1->name[i]!=0; i++)
test1->name[i]=0;
答案 2 :(得分:1)
正如评论中所提到的,只需在memset
之前使用free
。
memset(test1, 0, sizeof(*test1));
free(test1);
答案 3 :(得分:1)
free()不会清除内存意义上的归零 - 它只是让它可以重用 - 而这正是这里发生的事情。如果您的意图是初始化已分配的内存,请考虑使用calloc()。
答案 4 :(得分:1)
你可以在释放之前使用memset(test1, 0, sizeof(test_str))
,这只会将分配的内存区域填充为0。
malloc算法实际上通过保留它创建的每个内存块的元数据来工作。因此,如果您刚刚分配/释放/重新分配相同的大小,您可能会使用完全相同的内存块,这可以解释为什么新地址是相同的。
答案 5 :(得分:1)
一般来说,C函数不会做任何事情,除了他们应该做的事情。 malloc
和free
只是分配并释放内存 - 仅此而已。这意味着他们不会删除任何字段。
创建结构时,一般技术是清理任何相关字段。实际上,考虑编写一个封装结构创建的函数,如下所示:
mytest create_struct(char* name, int id) {
mytest t = malloc(sizeof(test_str));
size_t nlen = strlen(name);
memcpy(t->name, name, nlen <= 127 ? nlen : 127);
t->name[127] = '\0';
t->Id = id;
return t;
}
如果您愿意,还可以考虑定义相应的删除功能。
void del_struct(mytest t) {
if (t) {
memset(t->name, 0, 128);
t->Id = 0;
free(t);
}
}