-2

There is a weird phenomena that I am currently encountering in C's dynamic memory deallocating function, free(). In short, I've got this struct:

struct person {
    char* name;
    char* address;
    int days[6]; //no work on sundays
};

And I've got a container struct for these structs:

struct person* people;

Now, I am aware of the fact that since I am allocating the person's name and address dynamically via malloc(), I am going to need to free() them accordingly, before freeing the people struct. The weird encountered behaviour happens when I free both the name and the address.If I only free one of the two, I get garbage printed out when dereferencing the (already dangling) pointer. But, if I free both, then the person's address won't get cleared, only the name. Here's my simple code debugging snippet:

printf("%s", people[person_counter].name);
printf("%s", people[7].name);
free(people[person_counter].name);
printf("%s", people[person_counter].name);
printf("%s", people[7].name);
//people[person_counter].name = NULL;
printf("%s", people[person_counter].address);
printf("%s", people[7].address);
free(people[person_counter].address);
printf("%s", people[person_counter].address);
printf("%s", people[7].address);

For debugging purposes I hardcoded the exact position of the to-be-freed person's data in the array. What happens, is that the first two lines print out the same name, after freeing they print out garbage. The address printing remains the same at all 4 places. What's more peculiar is that if I comment out the first free, the address will be printed the first two times, and it is going to be cleared afterwards. I understood that you cannot guarantee that the contents of the memory address after freeing won't be "the same as before", but here clearly the freeing process does not take place. As I couldn't really find any relevant info to this, help would be much appreciated.

EDIT: I was hoping that this would solve my little bit more complicated issue, but since it does not:

What I am doing is removing workers from my container struct and the simple logic that is used is that if they are not the last worker, the last worker's name and address (also working days) gets copied on the worker to be deleted and I am always freeing the last worker's data. I also noticed, that when I free both the name and both the address, the person's address stays the same, but the very next person's name will be garbage. This can be seen when I am printing out my list of workers. Is this indeterministic too, or how does another worker's name get cleared when I am sure I free only once, and then the name and the address (as desired) and not two names.

Example Worker1
add1
1

Example Worker2
add2
2

Example Worker8
add8
4

(null)add4
1

Example Worker5
add5
2

Example Worker6
add6
1

Example Worker7
add7
6

Output after I delete Example Worker3 and Example Worker8 gets copied to its place.

Toni Nagy
  • 133
  • 2
  • 11
  • 1
    Does this answer your question? [C - What Happens To Memory After free()?](https://stackoverflow.com/questions/18582089/c-what-happens-to-memory-after-free) – John Doe Mar 16 '20 at 12:37
  • 5
    Why are you dereferencing a pointer that has been `free`d? The behaviour is undefined. You can't say "clearly the freeing process does not take place". It has, whether it seems that way or not. – Weather Vane Mar 16 '20 at 12:38
  • So if I free them separately, 100% of the time I get garbage, but if I do not, the address stays the same. – Toni Nagy Mar 16 '20 at 12:40
  • 3
    Well, show me where is says "the contents of the memory will be 'cleared'." – Weather Vane Mar 16 '20 at 12:41
  • If you're running on Windows and compiling with MSVC, try that with a debug version of your build that links a debug version of the MSVC run-time.... – Andrew Henle Mar 16 '20 at 12:45
  • See my edit above please! – Toni Nagy Mar 16 '20 at 12:51
  • You cannot legally know if you get garbage because you are not allowed to look at that memory location any more after freeing it. If you break the law, don't expect it to happen according to your rules. – Gerhardh Mar 16 '20 at 12:56
  • 1
    From the edit, there might be something wrong with the coding. There isn't enough posted to be able to say, but it is unlikely to be library functions misbehaving. – Weather Vane Mar 16 '20 at 12:59
  • "when I free both the name and both the address, the person's address stays the same, but the very next person's name will be garbage." - that sounds like a problem in your application code, not the `free` library function. Somehow you've messed up your bookkeeping and are assigning pointer values incorrectly. I know, because I've done it more than once. – John Bode Mar 16 '20 at 13:27

1 Answers1

1

free isn’t required to clear or overwrite any memory - it’s only required to mark that memory as available for use. The behavior on attempting to reference that memory after it has been free-d is undefined; any result is possible.

John Bode
  • 119,563
  • 19
  • 122
  • 198