tags:

views:

103

answers:

4

1- How does this work:

char *ptr = "hi";

Now the compiler will put this string in the memory (I'm guessing the stack), and create a pointer to it? Is this is how it works?

2- Also if it is created locally in a function, when the function returns will the memory occupied by the string be freed?

3- Last but not least, why is this not allowed: ptr[0] = 'H'; ?

+1  A: 
  1. The compiler will put the pointer to the string in memory and put the address of the string "hi" in the pointer. The string itself will be in the code image of the program.

  2. The memory to the pointer will be freed.

  3. Because ptr as defined by your code points to a constant in the code image. You can't write to a constant.

Amardeep
2. The memory for the pointer will be freed, but the memory for the string will not. If your function is called again, the string has to come from somewhere.
Mark Ransom
+6  A: 

1) The string is not (normally) on the stack -- it'll typically be in an initialized data segment that's read directly from the executable file. The pointer is then initialized to the address of that string.

2) No.

3) Because the standard says it gives undefined behavior. Consider if you had something like this:

int a() { char *a = "a"; printf("%s\n", a); }
int b() { char *b = "a"; *b = 'b'; }

int main() { 
    b();
    a();
    return 0;
}

Now, when you print out a, do you expect to get the original value (a) or the updated valued (b)? Compilers can, but don't necessarily, share such static strings; some also mark that whole area read-only, so attempting to write to it will generate an exception.

From the viewpoint of the C standard, the only reasonable answer was to call it undefined behavior.

Jerry Coffin
+2  A: 
  1. The compiler will put the string "hi" somewhere in memory (it is not imposed where by the standard), and you don't know where, but you have to take into account that it may be placed in a read-only section of memory (though it's the compiler to decide). Then a pointer will be created that points to the beginning to this place in memory.

  2. The memory will not necessarily be freed, as in most cases this string will reside in the data section of memory (in the same place where your compiled instructions will be).

  3. This is not allowed, as the standard does not guarantee write access to such automatically allocated block of memory (see 1.). It may work on some systems/platforms/compilers but it is not guaranteed by the standard.

Michał Trybus
+1  A: 
  1. You might more accurately and robustly express it as:

    const char *ptr = "hi";

    Not only is the actualité then expressed in your code, but the compiler will also trap attempts to write to the memory pointed to by ptr. The string itself is a 'static constant' (and therfore not on the stack), the pointer is a variable initialised to the address on the string.

  2. No, only th epointer will be instantiated on the stack. The data will remain in static constant memory (typically as part of the code text segment). Most compiler/linker toolchains will match common strings so that if for example you have several instances of "hi" in your code, they will in fact all refer to the same single instance.

  3. It is undefined behaviour. Depending on how the text is stored, it may or may not work. Modern processors/OS's often implement protection mechanisms to protect the code segment from both modification and execution; because such strings are also normally in the code segment, an attempt to modify the string is likely to result in a run-time exception. It is far better to detect this error at compile time by declaring the pointer const.

    If you happen to be using a 16-bit DOS compiler or a target without memory protection, it may appear to work; but because common strings may me collated, you may be modifying the string referenced by more than one pointer. On an embedded target, the string may reside in ROM, in which case even if the access is not trapped as illegal, it will have no effect.

Clifford