0

What is the difference between char *p and char p[] in two below code:

#include<stdio.h>
#include<string.h>

void main()
{
    char source[]="stackflow";
    char target[0];
    strcpy(target,source);
    printf("%s", target);
}
#include<stdio.h>
#include<string.h>

void main()
{
    char source[]="stackflow";
    char *target;
    strcpy(target,source);
    printf("%s", target);
}

Why is the former working while the letter not?

Kousaka
  • 3
  • 2
  • This is undefined behaviour in _both_ cases. – SafelyFast Mar 17 '23 at 15:44
  • In the first program `target` is a buffer of size 0. As soon as you copy something (even a single byte) into this buffer your code exhibits undefined behaviour. It apperars to work because the source string is not very long and you get away with it. In the second case `target` is an uninitialized pointer that points nowhere. Dereferencing such a pointer is also undefined behaviour, but you simply don't get away with it. It's like crossing a red light and asking "why didn't I got overrun by a car"? – Jabberwocky Mar 17 '23 at 15:52
  • 1
    Not that it really matters in this case, but declaring arrays of length 0 is a constraint violation in standard C, but is allowed as an extension to the standard by the GCC compiler. – Ian Abbott Mar 17 '23 at 16:29
  • Note that Standard C does not allow arrays of size 0. GCC allows it as an extension. When you copy anything to `char target[0];`, you are writing out of bounds and therefore invoking undefined behaviour. With `char *target;`, you have an uninitialized pointer; copying anything to the address it points at is also invoking undefined behaviour; you have no idea where the data will be copied to. You must ensure you have enough space in the target area whenever you copy strings around (or any data, but strings are the most common source of abuse). – Jonathan Leffler Mar 17 '23 at 16:36

1 Answers1

1

In this code, it does not matter as both codes invoke undefined behaviour (UB).

  • in the first snippet target is an array of length zero and you write outside the array bounds (it has zero length)
  • in the second snippet target is an uninitialized pointer and you dereference it invoking UB.

You need to define a large enough array or allocate enough memory to accommodate the source string.

  • char target[strlen(source) + 1];
  • char *target = malloc(strlen(source) + 1);

When you pass an array or pointer to the strcpy they will behave the same because references are passed by value and arrays decay to pointers in expressions.

Why is the former working while the letter not?

Because it is the nature of undefined behaviour. C standard does not say what will happen if you execute the code invoking it. It may fail or not, format your disk, send you card details to hacker or maybe something else

0___________
  • 60,014
  • 4
  • 34
  • 74