0

I'm told that when initializing a string like so

char str[] = "Hello world!";

The compiler will allocate an area in constants memory(read only for the program) and then copy the string to the array which resides in the stack. My question is, can I read or point to the original string after modifying the copy I'm given, and how? And if not, why does the string even exist outside of the stack in the first place?

5
  • Well, how else is that data going to get into the correct place on the stack? Commented Jun 29, 2014 at 15:57
  • 4
    Why do you want to do this? We can probably help if you tell us what your real requirement is. Commented Jun 29, 2014 at 15:59
  • If str is not at block scope then it is not "in the stack". if it is at block scope and you never actually modify its contents, the compiler could optimize it out (and just refer directly to the string literal for reads). Commented Jun 29, 2014 at 16:36
  • I remember a similar question a few days ago. Commented Jun 29, 2014 at 16:42
  • Regarding specific question: can I read or point to the original string after modifying the copy I'm given, and how? see below. Commented Jul 1, 2014 at 17:07

5 Answers 5

1

It's done this way for space efficiency. When you write:

char str[] = "Hello world!";

it's compiled effectively as if you'd written:

static char str_init[] = "Hello world!";
char str[13];
strncpy(str, str_init, 13);

An alternative way to implement this might be equivalent to:

char str[13];
str[0] = 'H';
str[1] = 'e';
 ...
str[11] = '!';
str[12] = 0;

But for long strings, this is very inefficient. Instead of 1 byte of static data for each character of the string, it will use a full word of instruction (probably 4 bytes, but maybe more on some architectures) for each character. This will quadruple the size of the initialization data unnecessarily.

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

Comments

0

Because the program has to remember the string somewhere, i.e., your so-called "constant memory". Otherwise how can it know what values to assign when allocating the variable? Think about a variable with a given initial value. The variable is not allocated until declared. But the initial value must be stored somewhere else.

1 Comment

Well, it could compile it as if it were char str[13];str[0] = 'H';str[1] = 'e'; ...; str[12] = 0;
0

When this statement is compiled

char str[] = "Hello world!";

the compiler does not keep the string literal in the program. it is used only to initialize the array.

If you want to keep the string literal then you have to write the following way

char *s = "Hello world!";
char str[13];

strcpy( str, s );

4 Comments

@Oli Charlesworth In C string literals have type char [].
But attempting to modify such an array is UB; to prevent this, always use a const pointer.
@Oli Charlesworth Do not attempt to modify string literals.:)
@Oli Charlesworth I agree that it is better to use the qualifier const but in the example I showed in my post I wanted to underline that in C string literals have type char[].
0

When the program runs, "Hello world" will be stored in the constant part of the memory as a string literal, after that, the program will reserve enough space in the stack and copy character by character from the constant part of the memory. Unfortunately, you don't have access to the constant part that stores the string literal because you are telling the program that you want the values to be modifiable (string stored in stack), so it gives what you asked.

Comments

0

Most of your question has been addressed in the other answers, However, I did not see anyone address this one specifically:

Regarding your question: ...can I read or point to the original string after modifying the copy I'm given, and how?

The following sequence demonstrates how you can read the original after modifying a copy:

char str[] = "hello world"; //creates original (stack memory)

char *str2 = 0;//create a pointer  (pointer created, no memory allocated)

str2 = StrDup(str); populate pointer with original (memory allocated on heap)

str2[5]=0;  //edit copy:  results in "hello" (i.e. modified)  (modifying a location on the heap)

str; //still contains "hello world"  (viewing value on the stack)

EDIT (answering comment question)

The answer above only addressed the specific question about accessing an original string after a copy has been modified. I just showed one possible set of steps to address that. You can edit the original string too:

char str[] = "Hello world!"; //creates location in stack memory called "str",
//and assigns space enough for literal string: //"Hello world!", 13 spaces in all (including the \0)
strcpy(str, "new string"); //replaces original contents with "new string" //old contents are no longer available.

So, using these steps, the original values in the variable str are changed, and are no longer available.
The method I outline in my original answer, (at top) shows a way whereby you can make an editable copy, while maintaining the original variable.

In your comment question, you are referring to things such as system memory and constant memory. Normally, system memory refers to RAM implementations on a system (i.e. how much physical memory). By constant memory, my guess is that you are referring to memory used by variables created on the stack. (read on)

First In a development, or run-time environment, there is stack memory. This is usually defaulted to some maximum value, such as 250,000 bytes perhaps. It is a pre-build settable value in most development environments, and is available for use by any variable you create on the stack. Example:

int x[10];   //creates a variable on the stack 
             //using enough memory space for 10 integers.  

int y = 1;   //same here, except uses memory for only 1 integer value  

Second There is also what is referred to a heap memory. The amount of heap memory is system dependent, the more physical memory your system has available, the more heap memory you can use for variable memory space in your application. Heap memory is used when you dynamically allocate memory, for example using malloc(), calloc(), realloc().

int *x=0;        //creates a pointer, no memory allocation yet...
x = malloc(10);  //allocates enough memory for 10 integers, but the 
                 //memory allocated is from the _heap_  
                 //and must be freed for use by the system
                 //when you are done with it.
free(x);

I have marked the original post (above) with indications showing what type of memory each variable is using. I hope this helps.

2 Comments

Doesn't that just duplicate the string though? Perhaps the issue is I don't understand enough about system memory to be asking this question but if I declare "int x = 1;" is the value 1 stored in constant memory, then copied to the variable x? If not, I really don't understand why it has to be that way with a string
@Techmaster21 - It matters where, and how you create a variable, and in some instances how you provide memory. See my edit for details

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.