0

I just started learning the relationship between pointers and arrays. What I read from this thread(What is the difference between char a[] = ?string?; and char *p = ?string?;?) is the string pointed by the pointer can not be changed. But in the following piece of code, I can change the string pointed by pa from abc to abd without any problem.

int main()
{
    char *pa;
    pa="abc";
    cout<<pa<<endl<<endl;
    pa="abd";
    cout<<pa<<endl<<endl;
    return 0;

}

However, it does not work in this piece of code. Can someone explain the difference to me? Thank you very much!!

int main()
{
    char *pc;
    pc="abc";
    cout<<pc<<endl<<endl;
    *(pc+2)='d';
    cout<<pc<<endl<<endl;
    return 0;
}
Community
  • 1
  • 1
user3858
  • 129
  • 2
  • 3
  • 12
  • 2
    u want (`*(pc+2)`) to access the memory of the 3rd char, but ya, undefined behavior still since you are using a string literal. Those are supposed to be constants and are not to be modified. I suggest you skip `char*` and graduate to `std::string` btw – Karthik T Feb 19 '14 at 06:51
  • @KarthikT thanks, why is the string literal in my first piece of code editable? Would it help to understand the problem after learning the `std::string`? The pointer stuff is confusing. – user3858 Feb 19 '14 at 07:00
  • 1
    In your first example you are not editing but just replacing it with a new literal, as explained by 51k. Regardless, it is considered Undefined behavior to edit String literals in c++, which means it might work it, it might not, it might blow up the sun, etc. – Karthik T Feb 19 '14 at 07:02
  • 1
    With strings what you want is simply `std::string str= "abc"; str[2] = "d";` I havent used C++ in a while so that might have some minor errors. As you can see the string API is more natural and easy to use/understand – Karthik T Feb 19 '14 at 07:02

3 Answers3

3

In the first case you are not changing the string, actually, what is happening is first you were pointing to "abc" (pa="abc";) then you are making the pointer to point to "abd" (pa="abd";), the previous string i.e."abc" remains unchanged in the memory.

And in the second case your pc pointer is pointing to the same string, and the statement *(pc+2) = d tries to modify the value pointed by pc, which cannot be done.

51k
  • 1,381
  • 3
  • 12
  • 22
  • Thanks, one more question, in the first case, does `pa` create a new string `abc` in the memory, and then create another `abd` in the memory? Or pointer simply search for the strings (`abc` and `abd` ) that already exists in the memory? – user3858 Feb 19 '14 at 07:05
  • 2
    the strings "abc" and "abd" are already in the memory, to be precise in the `read only data section`. And the pointer does not search for the string, but rather the statement `pc="abc";` takes the address of abc, and puts it into `pa`.. :) – 51k Feb 19 '14 at 07:08
  • 1
    no the strings are not created at run time... basically a pointer can point to any memory within your process virtual address space.. then let that memory contain anything.. – 51k Feb 19 '14 at 07:31
  • sorry, I am a little slow on this, how could the pointer point to something that was not in the memory before? It does make sense when you say it can point to any memory within the process virtual address space. but if `kjfdjiureiu`(some random string) was not in the memory, should this string be created in the memory first, then let the pointer point to it? – user3858 Feb 19 '14 at 07:37
  • 1
    yes you should create this string, on heap using malloc, or on stack, then get the string as a user input, then store it in the memory and make your pointer point to that memory. – 51k Feb 19 '14 at 07:39
1

Normally, string literals are stored in read-only memory when the program is running. This is to prevent you from accidentally changing a string constant. That's what happened in the second example, i.e. you will get a segmentation fault error.

This didn't happen in your first example because you are not changing the string itself. Instead, you just changed char *pa from pointing to one string to another.

You may need to check out: Why do I get a segmentation fault when writing to a string initialized with "char *s" but not "char s[]"?


P.S. I recommend you to use string if you do need to change some part of it.

string pc = "abc";
pc[2] = 'd'; 

Here, read-only "abc" is copied into non-const pc to enable you to change its content.

Community
  • 1
  • 1
herohuyongtao
  • 49,413
  • 29
  • 133
  • 174
1

@user3858 I don't know whether you are aware of static,automatic and dynamic memory allocations or not but let me tell you that 'pa' is your automatic (pointer) variable initially pointing to a static memory region "abc" and which you later shifted it to point to some other memory region filled with "abd"."abc" and "abd" ,both are separate regions.And in your second program you are actually making a change in the "abc" region to make it "abd" and for which you are encountering an error.

arjun8012
  • 29
  • 5