Confusion in basic concept of pointers and strings [duplicate] - c

This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Closed 9 years ago.
In my GCC 32-bit compiler, the following code gives the output
char *str1="United";
printf("%s",str1);
output:
United
then should I consider char *str1="United"; the same as char str1[]="United"?

The two are not the same: char *str1="United" gives you a pointer to a literal string, which must not be modified (else it's undefined behavior). The type of a literal string should really be const but it's non-const for historical reasons. On the other hand, char str1[]="United" gives you a modifiable local string.

char* str = "United"; is read-only. You wouldn't be able to reach inside the string and change parts of it:
*str = 'A';
Will most likely give you a segmentation fault.
On the other hand char str1[] = "United"; is an array and so it can be modified as long as you don't exceed the space allocated for it (arrays cannot be resized). For example this is perfectly legal:
char str[] = "United";
str[0] = 'A';
printf("%s\n", str);
This will print Anited.

See the comp.lang.c.faq, question 1.32. It basically boils down to the fact that declaring the string in array form (char str[] = "foo") is identical to char str[] = {'f','o','o'}, which is identical to char str[] = {102, 111, 111}; that is, it is a normal array on the stack. But when you use a string literal in any other context it becomes "an unnamed, static array of characters, [which] may be stored in read-only memory, and which therefore cannot necessarily be modified." (And trying to modify it results in undefined behavior wherever it happens to be stored, so don't).

Related

Queries on declaring & initialising string and also string memory region [duplicate]

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
What is the difference between char s[] and char *s?
(14 answers)
Closed 3 years ago.
My question comes in three part.
char str[] = "hello!";
char *str1 = "heello!";
puts(str);
str1[1] = 1
puts(str1);
printf("%s\n", str1);
printf("%p\n", str1);
Ouput of code:
hello!
h1ello!
heello!
0x10735ef9b
1) I understand that when you're declaring a char * type, you're declaring a pointer that points to char type. And usually for pointer, since it contains the address of the variable its pointing to, when you print the pointer itself, you'll get the address stored in the pointer and only when you dereference the pointer, then you'll get the content stored in the variable the pointer is pointing to.
However for a char * type, why is it that it doesn't function like a regular pointer? You can print the content of the variable which the 'char *' pointer is pointing to without dereferencing it and also use it like a string variable(rather than a pointer) by changing the value of the str1[1] as shown above.
2) I was taught that you shouldn't declare a pointer variable as such in the topic of pointer:
char *str1 = "heello!";
because the pointer variable would be pointing to whatever address happens to be in the memory at that time, thus running a risk of changing the value in a memory location that you don't mean to and resulting in segfault.
Hence you should do the following:
char *str1;
char c;
str1 = &c;
*addr = "hello!"
By doing the above, you'll make sure that your pointer is pointing to the right location before dereferencing and writing to the location.
However in the notes on string, it says to declare and initialise as such:
char *str1 = "heello!";
I'm quite confused as to what I should follow now when declaring a char * pointer. Please help.
3) It says in my notes that the location of string is stored in a read only region of the memory called the text region.
Hence doing this:
char *str1 = "hello!";
str[1] = '.';
Will crash your program.
But when you do this:
char str2[7] = "hello!";
str2[1] = '.';
This is okay and will successfully change the second element in the string from 'e' to '.'
The explanation to this was that str1 points to a read only region in the memory, while str2 contains a copy of the string on the stack.
I do not understand how the above 2 different ways of declaring the string variable will make such a big difference when executing the code. Please help.
Thank you!
String literals like "heello!" are really read-only arrays of characters (including the string null-terminator).
With
char *str1 = "heello!";
you make str1 point to the first character of such an array.
And when you do str1[1] = 1 you attempt to modify the read-only array, which is forbidden and leads to undefined behavior (which can but doesn't have to lead to crashes).
That's why you either should use your own arrays for strings, or use const char * to point to literal strings.

Difference between char[] and char* in C [duplicate]

This question already has answers here:
What is the difference between char s[] and char *s?
(14 answers)
Closed 8 years ago.
I'm currently learning C and am having a bit of trouble understanding how to declare a string. I understand that in C, strings are simply arrays of characters. I've seen two different ways for declaring a string:
char[] some_string = "hello world";
and
char *some_string = "hello world";
When should each of these be used? Most code I've seen uses the char *some_string syntax, but I'm sure that there's a reason why. Thanks.
char some_string[] = "foo" declares a local array of size 4 which is initialized at run time with the values 'f', 'o', 'o', and '\0'. That memory is (probably) on the stack of the function. char *some_string = "foo" declares a pointer which is initialized to the location of a string which is initialized at compile time to the same values. The string char [] some_string = "foo" is a syntax error. The most relevant difference between the two is that, on many platforms, the latter is not writable. In other words, some_string[1] = 'a' will generate a segfault on some platforms if some_string was declared as a pointer rather than an array.

Pointers and Strings causing segmentation fault [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between char a[] = “string”; and char *p = “string”;
char *str = "Hello";
printf("%c",++*str);
This gives segmentation fault on linux with gcc.
The moment the first statement is changes to as
char str[10] = "Hello";
It works. What may be the reason?
It is undefined behaviour to attempt to modify a string literal.
The compiler is free to place it in read-only memory (as it probably does in your case). Attempting to modify read-only memory is what's probably triggering the segfault.
This statement char *str = "Hello"; stores the string "Hello" in RO-section and assigns the address of the area of RO-section(in which "Hello"is stored) to str. The data stored in RO-section cannot be modified thus you are getting a segfault.
char str[10] = "Hello";
is also wrong. You should instead write
char str[10];
strncpy(str,"Hello",sizeof(str));

strings in C- is char *str is really equivalent to char str []? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Difference between char *str="STRING" and char str[] = "STRING"?
Need some help with C programming
while this snip gets segmentation fault
int main(void) {
char* str ="abcde";
str[strlen(str)-1] ='\0';
printf("%s",str);
return 0;
}
If I put
char str [] ="abcde"; instead of the pointer that works perfectly, do you have an idea why so?
When you write char *str = "abcde"; you make a char pointer to a string literal, which you are not allowed to modify.
When you write char str[] = "abcde"; you make a char array and copy a string literal into it. This is just a normal char array so you are free to modify it.
It is undefined behaviour to modify a string literal. This is a deliberate design decision that allows string literals to be placed in special read only sections of the output program. In practice many compliers and platforms do this (marking it read only means you need only one copy of the strings in memory, even if there is more than one instance of the program running). This leads to the behaviour you observed on your platform.
char *str = "abcde";
str is a pointer to char that points to a string literal. String literals are stored in read only memory. You can't modify them.
char str[] = "abcde";
The string literal "abcde" is copied into the array str. So you can modify it.
char * is pointer to char (string literal) and char [] is an array of char. You can't modify string literal but you can modify char array.

Declaration of strings in C [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
Is it possible to modify a string of char in C?
What is the difference between char s[] and char *s in C?
There is something I don't understand about strings and pointers in C.
Suppose I have this declaration:
char str[] = "abc";
Then, if I attempt to modify it this way:
str[0] = 'b';
It will work.
But if I declare the string as a pointer to a char
char* str = "abc"
The attempt above will cause an access violation.
What I'm trying to understand is what exactly is the difference.
Thanks in advance
In The later example the compiler puts the string in the read only data section, so u can't modify it. But in earlier example you are declaring array of character which resides in stack hence you can modify content of this array.

Resources