1

So, I continue to learn about C. And I have some interesting question. If I am not mistaken to put stuff on heap, I must use malloc etc.. But what about char * str? In what memory segment will be str located? I read that it will be put on .bss segment.(that is why you can't change string in C). Is this correct? Or will it be put on stack?

And if yes, why there is no need to free this memory when program ends? Also in what memory segment code of each function sits? in other words to what segment the pointer to function will point? Thanks for the help! Just trying to better understand memory management in C.

taocp
  • 23,276
  • 10
  • 49
  • 62
Farseer
  • 4,036
  • 3
  • 42
  • 61
  • Maybe this could help http://stackoverflow.com/questions/14004302/how-c-strings-are-allocated-in-memory?rq=1 – Tim Mar 22 '13 at 17:24
  • 1
    Declaring `char *str;` only allocates space for a single pointer object. If you want to to point to an array (which may or may not contain a string), that memory has to be allocated by some other means, either by calling `malloc()`, by using a string literal, by defining an array object, or something else. – Keith Thompson Mar 22 '13 at 17:25
  • Hi. My question is where will this memory sit? On stack or on bss segment? – Farseer Mar 22 '13 at 17:29
  • @Farseer where you allocate it. – wRAR Mar 22 '13 at 17:31
  • Your question should probably be something along the lines of "Where is a string literal stored? – davrieb Mar 22 '13 at 17:49
  • 1
    C doesn't even require the existence of a stack. Most implementations use one, but it isn't a part of the standard. – Randy Howard Mar 22 '13 at 20:46

6 Answers6

4

If you just say char * str the memory for the array will not be allocated, only the memory for the pointer itself. You will need to allocate the memory for the string manually, probably on the heap, and probably free it manually too.

"You can't change a string in C" is wrong. You cannot change a string constant, and string constants are allocated in something like .rodata (a readonly section). The functions code, like any other code, sits in something like .text.

wRAR
  • 25,009
  • 4
  • 84
  • 97
4

If you put a definition char *str; inside a function, then it's an automatic variable of type "pointer-to-char".

It's located on the stack, and that part of the stack becomes unused when the function returns (the compiler handles this for you by emitting code to move the stack pointer as necessary). In theory the existence of a stack is purely an implementation detail, in practice C always has a call stack, almost all implementations manage that more or less the same way, and however it is actually managed, the memory in which automatic variables is stored is liable to be referred to as "the stack".

If you put a definition char *str; outside any function, then it's a global variable with static storage duration.

It is stored in a read-write data segment, and becomes unused when the program exits (probably the OS handles this for you, although it could in principle be code emitted by the compiler). Since it is zero-initialized (and assuming an architecture on which a null pointer is represented by all bits zero) yes, it can go in the bss segment, which is specifically for zero-initialized read-write objects with static storage duration. Again, the details of how objects of static duration are stored is up to the implementation but again, this is how its generally done.

None of this has anything to do with string literals being unmodifiable, because you haven't defined a string (let alone used a string literal). You've defined a pointer, which could point to a string but does not (yet) do so.

Steve Jessop
  • 273,490
  • 39
  • 460
  • 699
2

In C, all local variables will be put on the stack. The variable str is a character pointer. It contains a memory address. On the stack will only be this pointer called str.

char * str;

This allocates memory with the size of a pointer (4 or 8 bytes on 32/64 bit) on the stack.

str = malloc(1024);

malloc allocates 1024 bytes on the heap and returns a pointer to the first byte of that memory area. This pointer is saved in str which is located on the stack.

Your variable str will be free'd when the function (in which str is a local variable) returns.

The memory area str is pointing to will not be free'd automatically. You need to do this manually with free(str).

Strings can be modified! But not constant literals:

char string[4] = "foo";
string[0] = 'F'; //will work

char * stringconst = "foo";
stringconst[0] = 'F'; // this will segfault

The above will not work, because "foo" will be placed (hopefully) in readonly memory areas.

flyingOwl
  • 244
  • 1
  • 5
2

I think you've confused pointers and what they point to. Take this:

char *str = "Hello";

If that's declared at file scope, then str is a pointer allocated statically. The string it points to is entirely separate. You can have str point to anything.

If instead it's declared in a function, then str is a pointer allocated on the stack. Again, the literal is separate.

In fact, if you have these two lines:

char *str1 = "Hello";
char *str2 = "Hello";

The compiler is free to have each pointing to the same address in memory.

The string literal is statically allocated regardless of the pointers, and it is placed (in general) in the initialised read-only data segment.

Also bear in mind that all concepts of heap, stack and segments are purely associated with the implementation, not the language.

teppic
  • 8,039
  • 2
  • 24
  • 37
1

Just two links I found while reading the answers to a similar question. These might help you understand the matter a bit better.

Memory Layout of C Programs and Storage for Strings in C

davrieb
  • 559
  • 2
  • 7
0

In C, We can refer string either by character array or character pointer.

Case 1 : If string is referred as character array :

char[] = "storage of strings";  

if the above declaration is GLOBAL then this is stored in DATA segment otherwise this will be stored in STACK segment.

Case 2 : If string is referred by a character pointer and memory is allocated at run time i.e using malloc, calloc.

char *str = (char *)malloc(sizeof(char)*size);  

In this case memory is allocated from the HEAP Segment.

Case 3 : If string is referred by character pointer and string value is assigned directly to char pointer.

char *str = "storage of strings"  

In this case this will be stored in DATA segment.It is like a string literal is allocated a memory in data segment and address of this string literal is assigned to str variable.

PS : Every memory which is assigned at run time (HEAP Segment) needs to be freed up in the program itself. so you need to use free() if you are using malloc,calloc or any function which assigns memory at run time.

SJ26
  • 29
  • 7