Reputation: 8052
I understand that following code returns segmentation fault because it tries to write to the part of memory where q
points to (some random address) and this part of memory is not allowed to write by given process:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char* p = "Hello";
char* q;
strcpy(q, p);
printf("%s\n", q);
}
I also understand that it can be easily fixed by dynamically allocating appropriate amount of memory and pointing q
to this memory, so p
content can be safely copied to q
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char* p = "Hello";
char* q = (char*)malloc(6*sizeof(char));
strcpy(q, p);
printf("%s\n", q);
}
But why following example is working?
#include <stdio.h>
int main(){
char* p = "Hello";
printf("%s\n", p);
}
Isn't char* p = "Hello";
also pointing to some unknown memory which is not allowed to write by given process?
Upvotes: 0
Views: 90
Reputation: 149135
When you write char *p = "Hello";
, the compiler internally creates a const char[6]
to hold the string litteral, and then copy its address to p
. Unfortunately, the type of a string litteral is not const, so you do not get any warning telling you that you are dropping a const
attribute, but the string litteral shall not be modified.
So p
point to a well defined memory zone and you can safely read from it for example with printf("%s\n", p);
The problem is that the string litteral shall not be modified, and trying to use the pointer for writing like in p[1] = 'a';
invokes undefined behaviour. In common implementations, the compiler actually uses a read-only segment to store string litterals and you get a memory violation or segment violation error if you try to overwrite it.
But it is not unknown memory simply read-only one.
Upvotes: 1
Reputation: 7212
When you write char* p = "Hello";
, the compiler will create a char
array in a part of memory that is read-only at runtime, filled as {'H', 'e', 'l', 'l', 'o', '\0'}
. The pointer p
is filled with the address of this array. So the address is valid, it can be read from safely but not written to, it can be passed as a readable string to C's string functions, and you never need to worry about malloc
ing and free
ing string literals because they represent static arrays.
Upvotes: 1
Reputation: 1041
The code
char* p = "Hello";
creates an array of six chars and sets them to "Hello"
(the sixth char is the null-char). Then, it writes the memory address of this array to p
. So p
points to an initialized memory segment.
Concerning your second example: p
contains the memory address of the char array "Hello"
. If you want q
to contain the same memory address, you have to use the command
q = p;
In the code
q = &p;
the types are incompatible, because q
has type char*
, whereas &p
has type char**
.
Upvotes: 2