c - Struct causing sysMalloc assertion to fail and double free() errors -
i writing simple struct called process, , code seems implemented correctly @ quick glance, upon testing code seems keep crashing program, either sysmalloc assertion failure or double free() error when 1 attempts free it.
some relevant code:
declaration
typedef struct process{ int pid; int background; int group; int status; char* name = 0; } process;
constructor
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; }
calling code
char* command = "python"; char* command1= "cat < testing"; process* proc = process_init("command", 1, 1, 1); process* proc2 = process_init("command1", 1, 1, 1);
there weird behavior appears work first time around, causes sysmalloc error when called second time (which why call twice.)
i tried using valgrind , gave me following:
invalid write of size 4 ==3485== @ 0x8049a03: process_init (process.c:6) ==3485== 0x80488c2: main (test.c:58) ==3485== address 0x419e730 12 bytes after block of size 4 alloc'd ==3485== @ 0x402425f: calloc (vg_replace_malloc.c:467) ==3485== 0x80499f9: process_init (process.c:5) ==3485== 0x80488c2: main (test.c:58) ==3485== ==3485== invalid write of size 4 ==3485== @ 0x8049a14: process_init (process.c:8) ==3485== 0x80488c2: main (test.c:58) ==3485== address 0x419e728 4 bytes after block of size 4 alloc'd ==3485== @ 0x402425f: calloc (vg_replace_malloc.c:467) ==3485== 0x80499f9: process_init (process.c:5) ==3485== 0x80488c2: main (test.c:58) ==3485== ==3485== invalid write of size 4 ==3485== @ 0x8049a1d: process_init (process.c:9) ==3485== 0x80488c2: main (test.c:58) ==3485== address 0x419e724 0 bytes after block of size 4 alloc'd ==3485== @ 0x402425f: calloc (vg_replace_malloc.c:467) ==3485== 0x80499f9: process_init (process.c:5) ==3485== 0x80488c2: main (test.c:58) ==3485== ==3485== invalid write of size 4 ==3485== @ 0x8049a23: process_init (process.c:10) ==3485== 0x80488c2: main (test.c:58) ==3485== address 0x419e72c 8 bytes after block of size 4 alloc'd ==3485== @ 0x402425f: calloc (vg_replace_malloc.c:467) ==3485== 0x80499f9: process_init (process.c:5) ==3485== 0x80488c2: main (test.c:58) ==3485== ==3485== invalid write of size 4 ==3485== @ 0x8049a03: process_init (process.c:6) ==3485== 0x80488ea: main (test.c:59) ==3485== address 0x419e768 12 bytes after block of size 4 alloc'd ==3485== @ 0x402425f: calloc (vg_replace_malloc.c:467) ==3485== 0x80499f9: process_init (process.c:5) ==3485== 0x80488ea: main (test.c:59) ==3485== ==3485== invalid write of size 4 ==3485== @ 0x8049a14: process_init (process.c:8) ==3485== 0x80488ea: main (test.c:59) ==3485== address 0x419e760 4 bytes after block of size 4 alloc'd ==3485== @ 0x402425f: calloc (vg_replace_malloc.c:467) ==3485== 0x80499f9: process_init (process.c:5) ==3485== 0x80488ea: main (test.c:59) ==3485== ==3485== invalid write of size 4 ==3485== @ 0x8049a1d: process_init (process.c:9) ==3485== 0x80488ea: main (test.c:59) ==3485== address 0x419e75c 0 bytes after block of size 4 alloc'd ==3485== @ 0x402425f: calloc (vg_replace_malloc.c:467) ==3485== 0x80499f9: process_init (process.c:5) ==3485== 0x80488ea: main (test.c:59) ==3485== ==3485== invalid write of size 4 ==3485== @ 0x8049a23: process_init (process.c:10) ==3485== 0x80488ea: main (test.c:59) ==3485== address 0x419e764 8 bytes after block of size 4 alloc'd ==3485== @ 0x402425f: calloc (vg_replace_malloc.c:467) ==3485== 0x80499f9: process_init (process.c:5) ==3485== 0x80488ea: main (test.c:59) --snip--
so, looks problem in constructor, i'm not sure why since looks straightforward moving around of variables.
process* output = (process*)calloc(1, sizeof(process*));
this incorrect. you're allocating enough memory pointer (4 or 8 bytes).
the proper code:
process* output = calloc(1, sizeof(*output));
improvements:
- it's correct! allocating enough bytes whatever
output
points to,process
, instead of enough bytes pointerprocess
. - by saying
sizeof(*output)
, remove additional reference type name (dry), ensures code correct, if changes typeoutput
points to, , forgets change rest of line. - i've removed cast result of
calloc
.calloc
returnsvoid*
can assigned pointer type variable without cast.
also, should checking return value of function, 1 returns memory:
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; }
any consumer of function should check return value well.
Comments
Post a Comment