0

hello to all programmers, I can't understand something

  1. char a[]="hello"

  2. char* b="salam"

the first question is why can't we modify 2,for example b[0]='m', I know that 2 gets stored as compile time constant BUT I can't understand what does it mean and what is the quiddity of 2 ?

and second question:

3.

char a[]="hello";

char* c=a;

c[0]='r';

Now we can modify and then print c, but we couldn't modify 2 ! why?

I can't understand the concept of those pointers please explain it to me

0

3 Answers 3

5

char a[] = "hello;" is a null terminated array of characters, the array will be initialized with the charaters you specify and the size of it will be deduced by the compiler, in this case it will have space for 6 characters, these are mutable, the charaters are copied to the array, you can change them at will. e.g. a[0] = 'x' will change hello to xello.

char* c = a; just makes the pointer c point to a, the same operations can be performed in c as you are really operating in a.

char* b = "salam" is a different animal, b is a pointer to a string literal, these are not meant to be modified, they don't get stored in an array like a, they are read only and are usually stored in some read only section of memory, either way the behavior of editing b is undefined, i.e. b[0] = 'x' is illegal as per the language rules.

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

Comments

3

char a[]="hello";

This creates an array like this:

   +---+---+---+---+---+----+
a: | h | e | l | l | o | \0 |
   +---+---+---+---+---+----+

The array is modifiable and you can write other characters to it later if you like (although you cannot write more than 5 or 6 of them).

char* b="salam";

This uses a string literal to create a constant string somewhere, that variable b is then a pointer to. I like to draw it like this:

   +-------+
b: |   *   |
   +---|---+
       |
       V
     +---+---+---+---+---+----+
     | s | a | l | a | m | \0 |
     +---+---+---+---+---+----+

There are two differences here: (1) b is a pointer, not an array as a was. (2) the string here (that b points to) is probably in nonwritable memory. But a was definitely in writable memory.

char* c=a;

Now c is a pointer, pointing at the earlier-declared array a. The picture looks like this:

   +---+---+---+---+---+----+
a: | h | e | l | l | o | \0 |
   +---+---+---+---+---+----+
     ^
     |
      \
       |
   +---|---+
c: |   *   |
   +-------+

And the array a was modifiable, so there's no problem doing c[0] = 'r', and we end up sounding like Scooby-Doo and saying:

   +---+---+---+---+---+----+
a: | r | e | l | l | o | \0 |
   +---+---+---+---+---+----+
     ^
     |
      \
       |
   +---|---+
c: |   *   |
   +-------+

The key difference (which can be quite subtle) is that a string literal in source code like "hello" can be used in two very different ways. When you say

char a[] = "hello";

the string literal is used as the initial value of the array a. But the array a is an ordinary, modifiable array, and there's no problem writing to it later.

Most other uses of string literals, however, work differently. When you say

char *b = "salam";

or

printf("goodbye\n");

those string literals are used to create and initialize "anonymous" string arrays somewhere, which are referred to thereafter via pointers. The arrays are "anonymous" in that they don't have names (identifiers) to refer to them, and they're also usually placed in read-only memory, so you're not supposed to try to write to them.

2 Comments

one of the most common duplicates.
@0___________ Indeed, and I should have searched for one. Thanks.
0

Let's start of with your first question:
We have 2 strings, a and b

char a[] = "hello";
char *b = "salam";

The first string can be modified, this is because it uses a different memory segment than the second string. It is stored in the data segment of the program, and we have write access to the data segment so we can modify it.

The second string is a pointer to a string, we cannot modify string literals (pointers to strings) since c specifies that this is undefined behavior.

The address of b will just point to somewhere in the program where that string is stored. This string should preferably be declared const since it can't be modified anyways.

const char *b = "salam";

Now let's look at the second question: The code you provided for the second question is perfectly valid,

char a[] = "hello";
char *c = a;,
c[0] = 'r';

We have a, which stores the actual string and if using ASCII it consists of 6 bytes 'h', 'e', 'l', 'l', 'o', '\0' c points to a we can verify this with this code

#include <stdio.h>

int main(void) {
    char a[] = "hello";
    char *c = a;
    c[0] = 'r';
    printf("a: %p\nc: %p\n", &a, &*c);
}

And we'll get output as such

a: 0x7ffe3c94ecf2
c: 0x7ffe3c94ecf2

They both point to the same address, the start of the array when we do

c[0] // It essentially means *(c + 0) = in other words the address which c points to + 0 and then we subscript this is how subscripting works a[1] = *(a + 1), etc...

So pretty much c in this case points to

0x7ffe3c94ecf2

c + 0 =

0x7ffe3c94ecf2

Access that address and modify the character.

6 Comments

The second string is a pointer to a string, that string is stored in rodata / text segment, which is a read only segment, we cannot write to that memory, we do not have the privileges to do that. Generally C does not know anything about the segments. It is about the implementation. Modifications of string literals is UB and shall not be performed.
Yes you're correct we're not certain about which segment it is stored in but this is most likely the case at least on windows / unix
maybe arduino? Atmega ? AVR8 bit where string literals are in RAM? How can you know
Like i said, yes you're correct we're not certain about which segment it is stored in. But i think it's safe to say most people write in a Unix / Windows environment. Sorry i assumed he isn't using DOS or Arduino lol
You assumption is wrong. I do programming in C as my daytime job for 30y. And I almost never program unix or windows systems. Simply remove that segment part from your answer. Attempt to modify the string literal is UB. C standard says that.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.