2

For example, if I have:

char arr[] = "this is a test";

but I decided I wanted to shrink it by 5 so I do:

arr = &arr[5]:

I tried this out and it seemed to work fine, Im just wondering if this would lead to any undefined behavior or "memory issues".

exliontamer
  • 95
  • 12
  • 5
    Uhm, that doesn't work at all, it should not even compile since you can't assign or change an array once defined. – Some programmer dude Jul 10 '18 at 08:11
  • 2
    This code would fail to compile, however you could write `char *arr2 = &arr[5];` and use `arr2` – M.M Jul 10 '18 at 08:12
  • I did this exact thing and it didnt fail to compile. I got no warnings, and it printed out fine – exliontamer Jul 10 '18 at 08:15
  • 2
    @JamesBrowning Post a [mcve]. – user3386109 Jul 10 '18 at 08:16
  • 2
    Do you pass `arr` to a function, and to the "shrinking" in the function? Then it builds because `arr` is no longer an array but a *pointer*. It won't really change the original array though. – Some programmer dude Jul 10 '18 at 08:19
  • @Someprogrammerdude Ahh yes that is exactly what I did, I see where I was confused. I have a char *ptr as a parameter, and I passed my string into the function. I then did ptr = &ptr[5] successfully. I thought that an array name was essentially identical to a pointer, but I guess they are different – exliontamer Jul 10 '18 at 08:29
  • It's a common confusion for beginners, because arrays can *decay* to a pointer to its first element. That decay makes arrays and pointers *mostly* compatible, but they are not the same. – Some programmer dude Jul 10 '18 at 08:39
  • re: [your recent question](https://stackoverflow.com/questions/51624350/how-does-declaring-an-array-in-c-affect-the-stack-pointer-gdb-assembler-code) which you deleted before I had a chance to reply: It's apparently a side-effect of gcc `-fstack-protector-strong` to not use the red-zone for arrays, at least with optimization disabled. https://godbolt.org/g/pzzHz5 shows un-optimized output for with/without stack-protector. It's possibly not a duplicate, but the answer isn't all that interesting. gcc does sometimes reserve more space than it needs even to maintain 16-byte stack alignment :/ – Peter Cordes Aug 01 '18 at 02:21

1 Answers1

5

No, this code would not even compile. It gives this error message:

error: assignment to expression with array type
     arr = &arr[5];
         ^

What you could do is this:

char arr[] = "this is a test";
char *ptr = arr;
printf("Before: %s\n", ptr);
ptr = &arr[5];
printf("After: %s\n", ptr);

If this is a good idea or not depends on the situation. Since arrays are allocated on the stack it's pretty safe. It will not lead to memory leaks.

Here is an interesting twister on the subject. How about writing this?

char * arr = "this is a test";

Then you have a pointer and no array, right? Well, this code does indeed allow you to perform the reassignment arr = &arr[5]. However, this is NOT equivalent to this:

char str[] = "this is a test";
char * arr = malloc(strlen(str));
strcpy(arr, str);

It is instead equivalent to this:

static char _unnamed_[] = "this is a test";
char * arr = _unnamed_;

One difference between these two is if you are returning arr from a function. Another is if you are calling free on it.

Arrays vs pointers

In a comment to your post you "thought that an array name was essentially identical to a pointer", which is wrong. It is very easy to make this mistake, and I have done it thousands of times, and I have had my fair share of humble pie here at SO on that matter. But arrays are not pointers. However, an array does in many cases decay to a pointer, which is exactly what's happening on the line char *ptr = arr above.

There are many questions with enlightening answers about this. Here is two:

What is the difference between char array vs char pointer in C?

Why do I get a segmentation fault when writing to a string initialized with "char *s" but not "char s[]"?

Actually, the array decaying to a pointer is also what's happening on the line ptr = &arr[5]. According to the definition of the [] operator, this is the same as writing ptr = &(*(arr + 5))

Why is a[5] the same as 5[a]?

klutt
  • 30,332
  • 17
  • 55
  • 95