Home > Blockchain >  using function malloc() and free(), problems with initialized pointer
using function malloc() and free(), problems with initialized pointer

Time:06-19

I'm not that new to coding but I faced a problem I couldn't explain to myself.

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char    *test;

    test = (char *)calloc(15, sizeof(char));
    // test = "Wurstbrot";
    free(test);
}

If I compile this, test gets malloced and directly freed (what I expected). But if I uncomment the comment, I get this error while compiling:

a.out(28953,0x104403dc0) malloc: *** error for object 0x10365cfae: pointer being freed was not allocated
a.out(28953,0x104403dc0) malloc: *** set a breakpoint in malloc_error_break to debug
zsh: abort      ./a.out

When I remove the free function, it will work again.

My question now: why is it a problem here to free an initialized pointer?

CodePudding user response:

free must be passed a null pointer or a valid pointer to a block allocated by malloc(), calloc(), realloc(), strdup() or another heap allocation function.

If you uncomment test = "Wurstbrot"; the pointer will point to static data, the string literal "Wurstbrot". Passing this address to free() has undefined behavior.

Passing test uninitialized would have undefined behavior too. If you are lucky, this uninitialized variable might happen to contain a null pointer, thus not causing a problem with free()... Undefined behavior is undefined, anything may happen including no visible side effect. A runtime error such as the one reported by the C library is actually quite useful to find bugs. no side effect is probably no luck in hindsight.

CodePudding user response:

When we analyze program run step by step:

A) Initialization before program starts running: A memory space on the stack is allocated and the string "Wurstbrot" '\0' is laid on that memory space. Say, that memory allocated for string starts at AAAA:0000; i.e. stack memory state is sth like below;

address     value
AAAA:0000   W
AAAA:0001   u
AAAA:0002   r
...
AAAA:0007   o
AAAA:0008   t
AAAA:0009   0 // that's a zero

B) When program starts running:

Line 1: A pointer variable is created. This variable sits on stack and is uninitialized. For a 32 bits system, this variable sits on the stack (say, at address AAAA:0020 to AAAA:0023 and contain some garbage value like DBAC:5782 that points to some random memory.

address     value
AAAA:0020   DB
AAAA:0021   AC
AAAA:0022   57
AAAA:0023   82

Line 2: Operating system allocates a memory space (probably on the heap) with a length of 15 bytes and hands the starting value to the program (say it starts from DDDD:0000). This value is assigned to your pointer variable and the pointer value on line 1 changes to DDDD:0000.

address     value
AAAA:0020   DD
AAAA:0021   DD
AAAA:0022   00
AAAA:0023   00

Line 3: test = "Wurstbrot"; line resets the value of the pointer to point to the memory that was allocated at step (A). From now on, your pointer variable test do not point to the allocated memory space on the heap but the initialized memory space on the stack.

address     value
AAAA:0020   AA
AAAA:0021   AA
AAAA:0022   00
AAAA:0023   00

Line 4: This line, of course, raise error. It tries to free the initialized memory space at step (A), not the memory space that was allocated at step (B)/1.

Solution:

Line 3 should read as: strcpy(test, "Wurstbrot");

  • Related