c - 如何在使用自由函数之前清理 C 中分配的内存?
问题描述
我创建了一个名为employee 的嵌套结构。我使用malloc从堆中为员工分配空间。然后,我使用free释放空间。据我所知,free函数只标记了一个可用于未来分配的位置。因此,分配内存的内容保留在内存中,并导致堆检查。
我在程序开始时定义的结构如下。
struct address{
char *city;
int zip;
}
struct employee{
char *name;
struct address add;
}
我实现了一个名为 sanitize 的函数,用垃圾值替换私有字段(0xAA
在本例中)。然后,我在 main 函数中测试了sanitize 。
void sanitize(char *ptr, int size){
memset(ptr, 0xAA, size);
}
int main()
{
struct employee* emp;
emp = malloc(sizeof(char) * 40);
emp->name = "John";
emp->add.city = "London";
emp->add.zip = 221;
printf("%s\n", emp->add.city);
sanitize(&(emp->add), sizeof(struct address));
printf("%s\n", emp->add.city);
return 0;
}
在运行时我得到分段错误。我的程序有什么问题?我应该如何以及以何种顺序清理嵌套结构?
提前致谢。
解决方案
确保为您的对象正确分配内存。这样做的功能有很大帮助。
struct employee *new_employee()
{
struct employee *emp = (struct employee*)malloc( sizeof(struct employee) );
if (emp)
{
emp->name = NULL;
emp->add.city = NULL;
}
return emp;
}
同样,创建一个销毁员工的函数:
struct employee *destroy_employee( struct employee *emp )
{
if (emp)
{
if (emp->name) free( emp->name );
if (emp->add.city) free( emp->add.city );
free( emp );
}
return NULL;
}
同样,您的清理功能需要了解员工:
void sanitize_employee( struct employee *emp )
{
if (emp)
{
if (emp->name) memset( emp->name, 0xAA, strlen( emp->name ) );
if (emp->add.city) memset( emp->add.city, 0xAA, strlen( emp->add.city ) );
emp->add.zip = 0xAAAAAAAA;
}
}
现在您可以轻松地创建和销毁员工:
struct employee *emp = new_employee();
emp->name = strdup( "John" );
emp->add.city = strdup( "London" );
emp->add.zip = 221;
...
sanitize_employee( emp );
emp = destroy_employee( emp );
请注意我们如何注意始终为每个对象分配空间,并适当地删除每个对象。您可以很好地结合消毒和销毁功能。
您的结构设计有一个重要问题。如果您更改员工的详细信息(例如,更改他的姓名),您的清理可能会失败,并且员工数据可能会未经清理。为此,您应该制定一个严格的政策,永远不要改变员工结构:使其成为 const,或创建额外的函数来改变数据并执行适当的清理和内存管理(清理、释放旧值、strdup
新值)。
您可能只想创建一个固定大小的记录来处理员工数据。这将大大简化您的生活,并使您不必处理同样多的内存管理员工职能。
推荐阅读
- c# - TextMeshPro 文本没有变化,控制台出现快速错误
- r - 在基本 R 热图的单元格中插入数字
- reactjs - 如何扩展 JSX.IntrinsicElements['div']?TS2499
- javascript - 如何从类json数组reactjs返回
- load-balancing - IBM Cloud 负载均衡器是否支持 WebSocket?
- testing - 是否可以在没有 db:create 和 db:migrate 的情况下在 rails 中运行测试?
- javascript - Ramda 的意外“sortBy”行为
- ruby-on-rails - 在 RoR 应用程序中请求资产时,Docker 返回 405(不允许)
- excel - 有没有办法通过 VBA 查找和选择第二个变量范围?
- http - 为什么我们需要 HTTP 而不是 SSH?