TheDoctor
TheDoctor

Reputation: 2522

Valgrind: is not stack'd, malloc'd or (recently) free'd

I have a struct "Turing" with an array of "Breakpoints" witch has a char array inside.

When i call calloc

machine.breakpoints_[free_counter].type_ = calloc(6, sizeof(char));

and do nothing with it valgrind doesn't complain when i free it.

but when i assign something to the variable for example:

machine.breakpoints_[free_counter].type_ = "12345";

valgrind raises an error when i use free on this variable.

Structs:

typedef struct _Breakpoint_
{
  char value_;
  char* type_;
} Breakpoint;

typedef struct _Turing_
{
  char* band_;
  int head_position_;
  int start_state_;
  int current_rule_;
  int current_state_;
  int rules_count_;
  Rules* rules_;
  Breakpoint* breakpoints_;
  int breakpoint_counter_;
  Boolean turing_over_;
} Turing;

main:

int main(int argc, char *argv[])
{
    Turing machine = {NULL, 0, 0,  0, 0, 0, NULL, NULL, 0, FALSE};

    machine.breakpoints_ = calloc(50, sizeof(Breakpoint));
    if(!machine.breakpoints_)
    {
      free(machine.breakpoints_);
      machine.breakpoints_ = NULL;
      printf(OUT_OF_MEMORY);
      return ERROR_CODE_OUT_OF_MEMORY;
    }

    int free_counter = 0;
    machine.breakpoints_[free_counter].type_ = calloc(6, sizeof(char));
    machine.breakpoints_[free_counter].type_ = "12345";
    machine.breakpoint_counter_++;

    for (; free_counter < machine.breakpoint_counter_; free_counter++)
    {
      free(machine.breakpoints_[free_counter].type_);       //line 133
      machine.breakpoints_[free_counter].type_ = NULL;
    }

    free(machine.breakpoints_);
    machine.breakpoints_ = NULL;
}

Valgrind is giving me this error:

==16989== Invalid free() / delete / delete[] / realloc()
==16989==    at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16989==    by 0x400A95: main (assb.c:133)
==16989==  Address 0x401b18 is not stack'd, malloc'd or (recently) free'd

and:

==16989== HEAP SUMMARY:
==16989==     in use at exit: 6 bytes in 1 blocks
==16989==   total heap usage: 2 allocs, 2 frees, 806 bytes allocated
==16989== 
==16989== 6 bytes in 1 blocks are definitely lost in loss record 1 of 1
==16989==    at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==16989==    by 0x400A50: main (assb.c:127)

What is wrong with my memory management there?

Please, tell me, if you nee further information.

Upvotes: 1

Views: 5343

Answers (2)

M.M
M.M

Reputation: 141638

"12345" is a string literal. They are not "stack'd or malloc'd", they are like global static variables. You cannot free one of these.

As you saw from your line

p = calloc(6, 1);

you would know that using = on pointer means to make the pointer point to the same thing that the right-hand side points to (in other words, p now holds the address you assigned to it).

The line

p = "12345";

is no different, you are making p stop pointing to the calloc'd space, and start pointing to the location of "12345".

If you intended to copy from the location of "12345" into the location pointed to by p, you're going to need to use some dereference operators, or a predefined function such as strcpy.

Upvotes: 3

Michael Albers
Michael Albers

Reputation: 3779

You need to use strcpy to copy the string into your value. Right now you're overwriting the calloc'd pointer to a string that's actually in your executable binary.

Upvotes: 3

Related Questions