【发布时间】:2020-09-23 06:54:47
【问题描述】:
通常在项目中使用复杂的结构,例如,如下所示:
struct opts {
char* server;
char* port;
int protocol;
void* protocol_data;
};
为了释放这些结构,直到今天我采用了如下例程:
void free_proto1(struct opts* opt);
void free_proto2(struct opts* opt);
void free_opts(struct opts** opt) {
free((*opt)->server);
free((*opt)->port);
if ((*opt)->protocol == PROTOCOL1) {
free_proto1(*opt);
}
else if ((*opt)->protocol == PROTOCOL2) {
free_proto2(*opt);
}
else
free((*opt)->protocol_data);
free(*opt);
*opt = NULL;
}
但是如果我有另一个struct opts 指针,比如struct opts* opts2 = opts1,那么在调用free_opts(&opt1) 之后再调用free_opts(&opt2) 肯定会导致程序崩溃。我知道编码的一个好习惯是避免这样的调用。但是有没有机会,我可以检测到内存已经被释放?我什至有兴趣查看Process Control Block(我认为所有程序信息都存放在那里)。我可以在执行free()'ing 操作之前仔细检查 PCB 结构,这样我就可以避免两次free()'ing 内存吗?
【问题讨论】:
-
没有办法防止像您描述的情况,您只需记录您的 API 并告诉用户不要愚蠢。如果他们然后做了一些愚蠢的事情,那是他们的错。
-
是的,只需创建您自己的函数来分配和释放,它会保留有关已分配内存块的索引。
-
#define FREE(A) do { free(A); A = NULL; } while (0) -
@Someprogrammerdude 我并不完全了解 Linux 内核如何管理内存中的进程,但我相信它会将内存分配的信息存储在某处。如果它存储了,我们不能在执行 free()ing 操作之前访问它吗?
-
@qrdl 这是一个非常方便的宏,但如果结构有我展示的指针,您可能会依赖垃圾收集器来释放该内存。而且,我担心的是,当再次调用相同的 FREE(B) (B = A) 时,程序会崩溃。
标签: c linux pointers memory-management free