-2

Please consider the following C++ code fragment. I am passing a reference to a char * as a parameter to a function.

void name(char **str){
    *str=(char *)"JUSTFORFUN";
}


int main(int argc, const char * argv[])
{
    char *test;
    name(&test);
    cout<<test; //Prints "JUSTFORFUN"
    //delete(test); //Throws error "pointer being freed was not allocated"
    return 0;
}

I think the memory allocated for storing "JUSTFORFUN" in function name() is allocated on a stack. So when the control goes out of name(), the memory associated with (char *)"JUSTFORFUN" should have been freed by the compiler. My question is why do I still get the correct output when I print test? Shouldn't it have printed a junk value?

When I do something similar for int. I get the expected result.

void nameint(int **value){
    int val=5;
    *value=&val;
}

int main(int argc, const char * argv[])
{
    int *val;
    nameint(&val);
    cout<<*val; //Prints a junk value 1073828160    
    return 0;
}

Why is there a difference between behavior of int and char * ?

Mishra
  • 85
  • 3
  • 9
  • 1
    "I think the memory allocated for storing "JUSTFORFUN" in function name() is allocated on a stack." - it's not. – Mat Jun 23 '13 at 05:44
  • @Mat - Please refer: http://stackoverflow.com/questions/51592/is-there-a-need-to-destroy-char-string-or-char-new-char6 – Mishra Jun 23 '13 at 05:46
  • 1
    That doesn't say anywhere that the string is allocated on the stack. It's not, it's a global (possibly stored in a read-only section). – Mat Jun 23 '13 at 05:47
  • @zmbq My immediate guesses are 1. dupe, 2. lack of research effort. –  Jun 23 '13 at 05:51
  • possible duplicate of [C++ string literal data type storage](http://stackoverflow.com/questions/2327841/c-string-literal-data-type-storage) – Jerry Coffin Jun 23 '13 at 05:57

4 Answers4

1

The string literal "JUSTFORFUN" is not stored on the stack -- it has static storage duration. Despite only appearing inside the function name, the string literal itself is not local to that function (no string literal is -- they all have static storage duration).

As such, the behavior of the first program is actually well defined. After name returns, val contains the address of a string literal with static storage duration, which you're then printing.

In your second program, you're returning the address of an int that's local to the function. After the function returns, that int no longer exists, so using it gives undefined behavior -- in a typical case it'll probably print out whatever value the bits currently at that address work out to, but there's no guarantee of what it'll do.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
1

"JUSTFORFUN" is not allocated on the stack. It's stored along with the rest of your program's static data. The name function stores a pointer on the stack. That pointer is pointing to the static data.

Your int, however, is stored on the stack. Your nameint function returns a pointer to that position on the stack. Doing something like that can cause your program to crash quite quickly.

zmbq
  • 38,013
  • 14
  • 101
  • 171
0

Two different cases:

In the string case, you didn't allocate any memory since raw strings like const char* x = "sdfsdf" are saved in the .data section of the executable so you can think about it as a static immutable data which is loaded with the program (no memory allocation allocation at all!)

On the second case val is allocated on the function stack and then it becomes invalid when the function returns.

Guy L
  • 2,824
  • 2
  • 27
  • 37
0

I think the memory allocated for storing "JUSTFORFUN" in function name() is allocated on a stack

No, it isn't. String literals implicitly have static storage duration. Their lifetime is that of the program. Without the delete, your first program is correct.

Throws error "pointer being freed was not allocated"

Of course it does, because you didn't create that object using new.

Why is there a difference between behavior of int and char *?

Because that's how the language is defined. In the second program, the int does have automatic storage duration (it's "stack allocated" with your words), so using its address outside its enclosing scope (which is the function here) invokes undefined behavior.