gpt4 book ai didi

c - 导致 sysMalloc 断言失败和双重 free() 错误的结构

转载 作者:太空宇宙 更新时间:2023-11-04 07:16:47 25 4
gpt4 key购买 nike

我正在编写一个名为 Process 的非常简单的结构,乍一看代码似乎已正确实现,但在测试我的代码时,程序似乎一直在崩溃,无论是由于 sysMalloc 断言失败还是由于 double free() 错误有人试图释放它。

一些相关代码:

声明

typedef struct Process{
int pid;
int background;
int group;
int status;
char* name = 0;
} Process;

构造函数

Process* Process_init(char* name, int pid, int group, int background){
Process* output = (Process*)calloc(1, sizeof(Process*));
output->name = name;
output->pid = pid;
output->group = group;
output->background = background;
output->status = 0;

return output;
}

调用代码

char* command = "python";
char* command1= "cat < testing";

Process* proc = Process_init("command", 1, 1, 1);
Process* proc2 = Process_init("command1", 1, 1, 1);

有一些奇怪的行为,它第一次似乎可以工作,但第二次调用时会导致 sysMalloc 错误(这就是我调用它两次的原因。)

我尝试使用 Valgrind,它给了我以下信息:

invalid write of size 4
==3485== at 0x8049A03: Process_init (process.c:6)
==3485== by 0x80488C2: main (test.c:58)
==3485== Address 0x419e730 is 12 bytes after a block of size 4 alloc'd
==3485== at 0x402425F: calloc (vg_replace_malloc.c:467)
==3485== by 0x80499F9: Process_init (process.c:5)
==3485== by 0x80488C2: main (test.c:58)
==3485==
==3485== Invalid write of size 4
==3485== at 0x8049A14: Process_init (process.c:8)
==3485== by 0x80488C2: main (test.c:58)
==3485== Address 0x419e728 is 4 bytes after a block of size 4 alloc'd
==3485== at 0x402425F: calloc (vg_replace_malloc.c:467)
==3485== by 0x80499F9: Process_init (process.c:5)
==3485== by 0x80488C2: main (test.c:58)
==3485==
==3485== Invalid write of size 4
==3485== at 0x8049A1D: Process_init (process.c:9)
==3485== by 0x80488C2: main (test.c:58)
==3485== Address 0x419e724 is 0 bytes after a block of size 4 alloc'd
==3485== at 0x402425F: calloc (vg_replace_malloc.c:467)
==3485== by 0x80499F9: Process_init (process.c:5)
==3485== by 0x80488C2: main (test.c:58)
==3485==
==3485== Invalid write of size 4
==3485== at 0x8049A23: Process_init (process.c:10)
==3485== by 0x80488C2: main (test.c:58)
==3485== Address 0x419e72c is 8 bytes after a block of size 4 alloc'd
==3485== at 0x402425F: calloc (vg_replace_malloc.c:467)
==3485== by 0x80499F9: Process_init (process.c:5)
==3485== by 0x80488C2: main (test.c:58)
==3485==
==3485== Invalid write of size 4
==3485== at 0x8049A03: Process_init (process.c:6)
==3485== by 0x80488EA: main (test.c:59)
==3485== Address 0x419e768 is 12 bytes after a block of size 4 alloc'd
==3485== at 0x402425F: calloc (vg_replace_malloc.c:467)
==3485== by 0x80499F9: Process_init (process.c:5)
==3485== by 0x80488EA: main (test.c:59)
==3485==
==3485== Invalid write of size 4
==3485== at 0x8049A14: Process_init (process.c:8)
==3485== by 0x80488EA: main (test.c:59)
==3485== Address 0x419e760 is 4 bytes after a block of size 4 alloc'd
==3485== at 0x402425F: calloc (vg_replace_malloc.c:467)
==3485== by 0x80499F9: Process_init (process.c:5)
==3485== by 0x80488EA: main (test.c:59)
==3485==
==3485== Invalid write of size 4
==3485== at 0x8049A1D: Process_init (process.c:9)
==3485== by 0x80488EA: main (test.c:59)
==3485== Address 0x419e75c is 0 bytes after a block of size 4 alloc'd
==3485== at 0x402425F: calloc (vg_replace_malloc.c:467)
==3485== by 0x80499F9: Process_init (process.c:5)
==3485== by 0x80488EA: main (test.c:59)
==3485==
==3485== Invalid write of size 4
==3485== at 0x8049A23: Process_init (process.c:10)
==3485== by 0x80488EA: main (test.c:59)
==3485== Address 0x419e764 is 8 bytes after a block of size 4 alloc'd
==3485== at 0x402425F: calloc (vg_replace_malloc.c:467)
==3485== by 0x80499F9: Process_init (process.c:5)
==3485== by 0x80488EA: main (test.c:59)
--Snip--

所以,看起来问题出在构造函数中,但我不确定这是为什么,因为它看起来像是一个非常简单的变量移动。

最佳答案

Process* output    = (Process*)calloc(1, sizeof(Process*));

这是不正确的。您只为一个指针(4 或 8 个字节)分配了足够的内存。

正确的代码:

Process* output    = calloc(1, sizeof(*output));

改进:

  1. 现在是正确的!我们正在为 output 指向的任何内容分配足够的字节,这是一个 Process,而不是为指向 Process 的 pointer 分配足够的字节
  2. 通过说 sizeof(*output),我们删除了对类型名称 (DRY) 的额外引用,这确保您的代码是正确的,即使有人更改了 的类型output 指向并忘记更改该行的其余部分。
  3. 我有 removed the cast来自 calloc 的结果。 calloc 返回 void*,无需强制转换即可将其分配给任何指针类型变量。

此外,您应该检查任何函数的返回值,特别是返回内存的函数:

Process* Process_init(char* name, int pid, int group, int background){
Process* output = calloc(1, sizeof(*output));
if (output == NULL)
return NULL;

output->name = name;
output->pid = pid;
output->group = group;
output->background = background;
output->status = 0;

return output;
}

这个函数的任何消费者也应该检查它的返回值。

关于c - 导致 sysMalloc 断言失败和双重 free() 错误的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23974339/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com