-1

The code is below.

My question is about the result. I want to understand, why after calling free(p) p->elem turns to '0', but the p->str still contains "hello"?

#define LEN (sizeof(struct node))
typedef struct node
{
       int elem;
       char *str;

}*p_node;
int main(void)
{
    p_node p;
    p=(p_node)malloc(LEN);
    p->elem=99;
    p->str="hello";
    printf("the p->elem:%d\n",p->elem);
    printf("the p->str :%s\n",p->str);
    free(p);
    printf("the p->elem:%d\n",p->elem);
    printf("the p->str :%s\n",p->str);
    return 0;
}

https://i.stack.imgur.com/rt1jf.png

DarkWanderer
  • 8,739
  • 1
  • 25
  • 56
a ask boy
  • 3
  • 3
  • Undefined behavior doesn't mean "always crash obligatorily". I don't know why everyone has so high expectations of inherently faulty code. –  Dec 27 '13 at 14:05

2 Answers2

3

Freeing memory doesn't actually clear the pointer or the memory it pointed to (except under specialized circumstances meant to assist in debugging problems like this -- never rely on the behavior though). Using a pointer after freeing the memory it pointed to is invalid, and is undefined behavior. It might as well crash, or cause random values to be printed.

Also, in C you should not cast the return of malloc.

Community
  • 1
  • 1
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

First, never do that in actual code. Your code works now only because the memory wasn't claimed by other allocations yet, and there's still a "ghost" of the old allocated struct.

On the actual question, your p->str pointer is pointing to a constant literal, i.e. a piece of text which is "hardcoded" in the application data. Hence, the pointer to it will be valid throughout application lifetime - here's a "more valid" example:

p_node p;
p=(p_node)malloc(LEN);
p->elem=99;
p->str="hello";
char* pstr = p->str;
free(p);
printf("the pstr :%s\n",pstr); // still outputs "hello", because pstr would be just a pointer to "hardcoded" data
DarkWanderer
  • 8,739
  • 1
  • 25
  • 56