0
int num = 0, k = 0;

scanf("%d %d", &num, &k);

int* A = #
    
for (int i = 0; i < num; i++)
{
    scanf("%d", &A[i]); //scanf("%d", A+i);
}

in that code, I want 4 5 1 3 2 integers put in the array A

input is

5 7
4 5 1 3 2

but in debug mode, there are

    *A  4           int
*(A+1)  5           int
*(A+2)  1           int
*(A+3)  3           int
*(A+4)  -858993460  int
*(A+5)  -858993460  int

why is the *(A+4) not 2??????

I tried the num+1, but that is not the ultimate solution.

for (int i = 0; i < num+1; i++)
{
    scanf("%d", &A[i]);
}
Vojtěch Chvojka
  • 378
  • 1
  • 15

3 Answers3

2

To define an array, you'd do

int A[num];

Your variable A is a pointer to an integer, not an array. You can treat it as an array, as arrays are basically pointers in C. But the memory you're writing from scanf() is not 'allocated'.

Vojtěch Chvojka
  • 378
  • 1
  • 15
  • 1
    that is a VLA, supported in C99 and above (but not C89, and not in Microsoft Compilers) – abelenky Mar 28 '23 at 12:41
  • `int *A = malloc(num * sizeof(int));` would be correct, but you'd need to provide some explanations. – Jabberwocky Mar 28 '23 at 12:49
  • to everyone, i want to thanks for your effort – Cheon SeockBeom Mar 28 '23 at 12:52
  • 1
    `int *const A = malloc(num*sizeof(int));` is *more* correct for the const-pointer. – abelenky Mar 28 '23 at 12:52
  • i just know why is the *(A+4) not 2?????? because i pointed integer name with A integer allocated 4byte so, sits that the A can point are 4 sits!! – Cheon SeockBeom Mar 28 '23 at 13:20
  • 1
    @CheonSeockBeom On your stack, there are 3 integers (`num, k, i`) and one pointer (`A`). `A` is address of `num`, `(A+1)` is probably address of `k` etc... `(A+4)` is just first place beyond stack, and you should not access that. – Vojtěch Chvojka Mar 28 '23 at 13:27
  • @VojtěchChvojka `*(A+1)` shouldn't accessed either, you don't know where it points. – Jabberwocky Mar 28 '23 at 14:10
  • @Jabberwocky Yeah, yeah. *Don't do that!* Just giving an explanation of why it was possible to write something there. – Vojtěch Chvojka Mar 28 '23 at 14:52
  • I *really* dislike the VLA recommendation here, especially on a beginner question. `num` comes from an unsanitized user input and this recommends doing a stack allocation based on it's size. That's just bad practice. Maybe at least use a fixed size array to keep it simple and point to a further resource like this very similar answer: https://stackoverflow.com/a/23240957/7204912 – ChrisB Mar 28 '23 at 16:31
  • @ChrisB VLA is great for simplicity. Security, sanitizing input, differences between stack and heap, etc, are different (but essential) topics for a later time, ***after*** learning to write code that just *works*. At this point, OP is trying to get their code to work. More advanced considerations come later. So I agree with your critique of VLAs, but I think they're acceptable for this point in the poster's programmer journey. – abelenky Mar 28 '23 at 16:44
  • @abelenky Recommending bad practice without at least acknowledging it in some way seems questionable. – ChrisB Mar 28 '23 at 16:53
1
int* A = &num;

There is no array in your code. A is a pointer that is initialized with the address of num, which is of type int.

The code then invokes undefined behaviour on the second iteration of the for loop because the memory after A doesn't belong to you.

To define an array, you'd write:

int A[ /* Number of elements */ ] 
Harith
  • 4,663
  • 1
  • 5
  • 20
-1

In C you need to allocate memory for your array, indeed. But the original code might look as woking for the first few elements (in some cases)

C compiler would not warn you about getting out of array bounds and even in runtime your code might not get terminated, so you don't always see your error from simple tests, which exactly happened with the original code

  • 1
    Nope, it doesn't work for `A[1]` to `A[3]`. It only _seems_ to work. It's undefined behaviour. One manifestation of undefined behaviour is "apparently working fine". The `A` pointer points to a single `int` (that is `num`), therefore only `A[0]` (or the equivalent `*A`) is valid. _"...because declaration of a single pointer to int creates just enough memory"_, no it doesn't create any memory. – Jabberwocky Mar 28 '23 at 14:06
  • Nevertheless, such behavior is a common trap to fall for – seabearious Mar 28 '23 at 14:26
  • Yes of course, but you shouldn't write that it works. And as I wrote before: the sentence _"...because declaration of a single pointer to int creates just enough memory"_ is plain wrong. `int num;` allocates memory for exactly one `int`. `A[1]` to `A[3]` also contain garbage. – Jabberwocky Mar 28 '23 at 14:34
  • In theory, declaration of a pointer allows you to place only one element (here, `A[0]`). Nevertheless, `sizeof(A)` gives me 8 bytes, while `sizeof(num)` gives me only 4 (on my system). Still, one should not rely on "seems to work" – seabearious Mar 28 '23 at 16:33