-5

I am in learning about pointers and strings and how they work. I have a question which answer may I know already. But, in fact, I want to be sure of it. Let take the following code for example:

char a[200],*p;
gets(a); // cin.get(a,200);
p=a;
strcpy(p,p+1);
printf("%s",a); // c
cout<<a; // cpp
return 0;

Input : working
Output : orking

So what about this? Why do the array modified without actually modify itself?

char a[200],*p;
gets(a); // cin.get(a,200);
p=a;
p++;
printf("%s",a); // cout<<a;
return 0;

Input : working
Output : working

In this case, why the array did not modify? What has the function strcpy special? And which other functions has this propriety?

Throughout the text, I have referred to the functions of the strings set in the program.

KroTeK
  • 67
  • 8
  • 2
    `printf("%s",a);` => `printf("%s",p);` – bruceg Oct 30 '17 at 22:42
  • I know that, but I was meaning about other types of exercices, where this equalization isn't true (at the final of the syntax). Like : int i=0; char a[200],b[200],*p; cin.get(a,200); strcpy(b,a); while(b[i++]!='*'); b[--i]='\0'; p=strstr(a,b); while(p!=NULL) { strcpy(p,p+strlen(b)); p=strstr(p,b); } cout< – KroTeK Oct 30 '17 at 22:48
  • As long as both the pointer point to the same memory then any change to one of them will affect equally the other. – Raindrop7 Oct 30 '17 at 22:53
  • And then why it doesn't change when i wrote p=p+1 ? – KroTeK Oct 30 '17 at 22:55
  • 3
    FIrst of all, `strcpy()` specifies that the strings MAY NOT overlap, so all bets are off on how it behaves. `++p` only changes `p`, the pointer, making in point to the next memory address. That doesn't affect the contents of that memory until you write through `p`. – Lee Daniel Crocker Oct 30 '17 at 23:02
  • `strcpy(p,p+1);` you copy string onto itself, since you copied pointer, minus 1st character, thus modifying the source. – Killzone Kid Oct 30 '17 at 23:02
  • Because you changed the pointer to point to another location. – Raindrop7 Oct 30 '17 at 23:02

2 Answers2

1

Snippet 1

char a[200],*p;

Defined a block of 200 characters ,a, and a pointer, p, to a block of one or more characters.

gets(a); // cin.get(a,200);

Read some user input into memory block a

p=a;

Points p at block a. p can now be used as a reference to the same thing as a

strcpy(p,p+1);

Copy part of the memory block over itself. NOTE: this invokes undefined behaviour because the to and from buffers in strcpy overlap (See http://en.cppreference.com/w/cpp/string/byte/strcpy). The results may be unusual, ranging from "Looks like it works!" to more fantastic, such as the computer making it rain unicorns.

So, say a is created at memory location 10. Data is read into the block starting at location 10. Then p is set to point at location ten. Then the memory starting at location 11 is copied over the memory starting at location 10. Since a is at 10, printing a prints the altered data. Since p is still pointing at 10, printing p will print the same thing as a.

Snippet 2:

char a[200],*p;

Defined a block of 200 characters ,a, and a pointer, p, to a block of one or more characters.

gets(a); // cin.get(a,200);

Read some user input into memory block a

p=a;

Points p at block a. p can now be used as a reference to the same thing as a

p++;

Moved where p pointed over one slot to the right. Copied nothing. Just changed the address that p points at.

So, say a is created at memory location 10. Data is read into the block starting at location 10. Then p is set to point at location 10. Then p is set to point at memory location 11. The values in memory block a are unchanged. Since a is still at 10, printing a prints the unchanged data. Since p is now pointing at 11, printing p will print the from the second character of a onward.

Community
  • 1
  • 1
user4581301
  • 33,082
  • 7
  • 33
  • 54
  • +1 Yes! exactly and that is the way Linked-list works. (for example in a linked-list print method we don't want to change the head pointer so we create a temporary one to walk memory...). – Raindrop7 Oct 30 '17 at 23:06
  • Thank you for this explanation. I have understand it. – KroTeK Oct 30 '17 at 23:13
  • a is not a block of 200 chars, a is a pointer to the start of a block of 200 chars. – nicomp Oct 30 '17 at 23:31
  • @nicomp `a` is not a pointer. `sizeof(a)` is not equal to `sizeof(p)`. – user4581301 Oct 30 '17 at 23:39
  • @user4581301 a is indeed a pointer. Your example is correct but that's an inconsistency of the original C language. a[0] is pointed to by a. – nicomp Oct 31 '17 at 09:51
  • @nicomp even in C `a` is not a pointer. `a` decays to a pointer. It is not a pointer. – user4581301 Oct 31 '17 at 16:19
  • @user4581301 You're still wrong. a is a pointer to a char. Try printf("%s", a) and see what you get. – nicomp Oct 31 '17 at 21:49
  • [Arrays decay to pointers](https://stackoverflow.com/questions/1461432/what-is-array-decaying) when you use them in a function call, so by the time `printf` gets its grubby hands on `a`, all it gets is a pointer. Here's another difference between array and pointer: https://ideone.com/OJzsAQ – user4581301 Oct 31 '17 at 22:00
  • @user4581301 Your code demonstrated the difference between a pointer constant and a pointer variable (a type of lvalue) . – nicomp Nov 03 '17 at 15:59
  • No it demonstrates a conversion from an array to a pointer, a prvalue. See [conv.array] in the C++ standard (and [basic.lval] for the definition of a prvalue). – user4581301 Nov 03 '17 at 17:43
0

You are not modifying anything in the second code. Why should it be modified? Piano points to the first element of a. Then you increment it. So please points to the second element. Then you print a, who wasn't modified.

As for the first one, from strcpy reference :

To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source(including the terminating null character), and should not overlap in memory with source

I think you have what is called an overlap. You copy a source to a destination that's overlapping in memory.

karim_g
  • 115
  • 11