0

Consider the following code (building with g++):

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

typedef struct {
    int a;
    int b;
    char c;
} memstr_t;

memstr_t *ptt_backup;

void mmm(memstr_t*& ptt)
{
    ptt = (memstr_t *)calloc(15, sizeof(memstr_t));
    ptt[0].a = 1;
    ptt[0].b = 2;
    ptt[0].c = 'c';
    ptt_backup = ptt;
}

void fff()
{
    free(ptt_backup);
}

int main(int argc, char *argv[])
{
    memstr_t *ptt;

    mmm(ptt);
    printf("%d %d %c\n", ptt[0].a, ptt[0].b, ptt[0].c);
    getchar();
    //fff();
    free(ptt); // same as fff()?
    printf("%d %d %c\n", ptt[0].a, ptt[0].b, ptt[0].c); //why works?
    getchar();
    return 0;
}

I don't understand:

1) Why I'm not getting segfault on the second print since I free the memory? I'm still getting the values which I assigned in mmm()

2) Are free() and fff() doing the same thing?

JBL
  • 12,588
  • 4
  • 53
  • 84

5 Answers5

2

1) Dereferencing free'd memory can do anything. It may be there, it may not, it is undefined behaviour and could do anything, including faxing your cat.

2) Yes, free() and fff() are doing the same thing as they both point to the same memory location.

Salgar
  • 7,687
  • 1
  • 25
  • 39
1

Second print uses pointer that is no longer valid, that makes behavior undefined. Whatever can happen, including what makes you believe it "works", and any other time it could be something completely else. DON'T DO THAT!

2: in this code fragment they have the same effect.

Balog Pal
  • 16,195
  • 2
  • 23
  • 37
0

calloc allocates memory and returns a pointer to the allocated memory.

In mmm you assign ptt to ptt_backup. Now both of them point to the same place. (Just because I have a name and a nickname , that doesn't make two copies of me. I am a single person accessible via two different names)

In fff you are freeing ptt_backup (read that as freeing the memory pointed by ptt_backup) which is also the one pointed by ptt.It means the memory is not available for you to use now. It can still retain values but its undefined to rely on it. See this nice answer, Can a local variable's memory be accessed outside its scope?

printf("%d %d %c\n", ptt[0].a, ptt[0].b, ptt[0].c); may not always work.

Then when you do free(ptt) (read that as freeing the memory pointed by ptt) which is already deleted by fff, it is undefined behaviour as stated,

The free() function shall cause the space pointed to by ptr to be deallocated; that is, made available for further allocation. If ptr is a null pointer, no action shall occur. Otherwise, if the argument does not match a pointer earlier returned by the calloc(), malloc(), [ADV] posix_memalign(), realloc(), or [XSI] strdup() function, or if the space has been deallocated by a call to free() or realloc(), the behavior is undefined.

Community
  • 1
  • 1
Suvarna Pattayil
  • 5,136
  • 5
  • 32
  • 59
0
  1. Using a memory pointer that points to freed memory leads to undefined behavior. This means that a segfault doesn't necessarily happen, but is possible. Therefore, you never should dereference freed memory.

  2. They (fff and free) are the same thing in this context, because they point to the same address.

user2448027
  • 1,628
  • 10
  • 11
-1

You never allocate memory for ptt_backup! You're in undefined behaviour land; anything could happen in fff()

Bathsheba
  • 231,907
  • 34
  • 361
  • 483