0

Consider this code:

char* f(char* str)
{
    return ++str;
}

int main()
{
    char* str = "test";
    str = f(str);
    //flag
    return 0;
}

At 'flag' what happens with the memory address where the first original 't' resides? Will it be free-ed or will it be a 'stack leak'?

1
  • char* str = "test"; allocate the string in the read only memory. Only the pointer str is allocated on stack, and its value is updated from the call to the function f(). No stack change happen. Commented Dec 21, 2019 at 14:55

2 Answers 2

2
char *str = "test";

There are 2 objects "in play" here: the str object of type char* (pointer to char) and the unnamed object of type char[5].

The unnamed array object (with contents {'t', 'e', 's', 't', 0}), when used as initialization value for a pointer get converted to a pointer to its first element and it's that address that gets copied to str.

There is no allocation of memory, so there is no chance of having memory leaking!

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the reply. What if I declared it explicitly like this char str[5] = {'t', 'e', 's', 't', 0}
Still no allocation. str is associated with an area of memory 5-bytes long but the management of that area is done automatically by the implementation; the programmer does not need to think about it -- it gets automagically created when the statement "is executed" and gets automagically destroyed when the encompassing } is reached.
ok but this could be a problem then right? if you did this with large data sets at the beginning of some high level function. Or main?
Yes, it could cause issues. For large objects it's better to use malloc() and friends. For example: int main(void) { char giga[1024*1024*1024]; } will probably fail in contrast with int main(void) { char *giga = malloc(1024*1024*1024); frre(giga); }
2

The string literal "test" will be welded into the executable, and the OS will place it in read-only memory (that's why attempts to modify string literals often trigger a segmentation fault) while loading the file. The OS is also responsible for properly unloading the data.

So, that data is not placed on the stack, but char* str is. Since it's a regular local variable, it'll be deallocated automatically by the code inserted by the compiler.

To answer the question: at //flag the whole content of "test" will still be present at the same address initially allocated by the OS, and the stack won't be involved here at all. While processing the return statement, the compiler will insert code to clean up the stack.

16 Comments

Ok thanks, what if I declared it like this: char str[5]; strcopy(str, "test");
@Lythoc, doesn't matter: the literal "test" will always be embedded into your executable and later stored in read-only memory by the OS.
Ok thanks again. :) Final question, is there a danger then to have 'leaks' in read-only memory? Does the OS ever do a garbage collection pass on it during runtime?
There is no requirement to place string literals in read-only memory. Implementations are free to place the array wherever they like best :)
@Lythoc, literals are part of the executable (because they're not supposed to be changed, like your program's bytecode), and are loaded and offloaded along with it. The OS cannot do garbage collection because it has no way of knowing if that data will ever be used again or not while the program is still running. Once it has finished execution, the OS has to offload the whole executable, and so all the constants will be gone too
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.