-1

I'm very new to C and I have trouble understanding array pointers. I'm trying to make a array bigger,I copy all of its element to new bigger array but I can't make original variable to point the new array. I'm use to C# where you can do

 double[] array1 = new double[5];
 double[] array2 = new double[10];
 array1 = array2; 

I did something similar using int array

int array1 [5];
int array2 [10];
*array1 = &array2;

and it compile but crash the program. Same lines but double or char[] (I was told to use char[] instead of sting in C) do not even compile [Error] incompatible types when assigning to type 'double' from type 'double (*)[(sizetype)(newsize)]' The results I found on the topic told me to use double* array1 for variable type but this change the interactions with that variable. If someone can explain the concept to me or at least tell me what to search for that will be huge help. I do know the basics of pointers!

Scheff's Cat
  • 19,528
  • 6
  • 28
  • 56
Tagap
  • 11
  • 1
  • As a beginner, you should always compile with `-Werror -pedantic-errors`. Will save you from confusion and wasting time trying to understand things where there's nothing valuable to understand. – Lundin Jun 05 '20 at 06:27

3 Answers3

2

There are a few things you need to know about arrays (and pointers):

  • The first is that arrays and pointers are two different things;

  • The second is that an array can decay to a pointer to its first element. So if you use array1 (from your example) when a pointer is expected, that's the same as doing &array1[0]. The type of such a pointer is a pointer to a single element type (so for array1 the type will be int *);

  • The third thing is that for any array of pointer a and index i, the expression a[i] is exactly equal to *(a + i). That means *array1 (again from your example) is the same as array1[0] (*array1 is equal to *(array1 + 0) which is equal to array1[0]);

  • An array will have a fixed size. Once defined the size of an array can't change;

  • Lastly when you get a pointer to an array (as in &array2) then you get a pointer to the actual array, not to one of its elements. The type of e.g. &array2 is int (*)[10].

Now we can puzzle together the statement

*array1 = &array2;

If we do the array-indexing replacement for *array1 then we get

array[0] = &array2;

And here we can see a big problem: The type of a single element of array1 is a plain int. So what the assignment is trying to do is to assign a pointer to an array (of type int (*)[10]) to a single int.


If you want to copy all the elements from one array to another, then use the memcpy function. You're not allowed to assign between arrays.

But beware of the different sizes for array1 and array2. If you go out of bounds of an array (or other allocated memory) you will have undefined behavior.

In C there is no way to make an array variable "reference" a different variable. If you need to use "references" they can be emulated using pointers:

int *pointer1 = array1;  // array1 here will decay to &array[0]
int *pointer2 = array2;  // Same here for array2

With the above definition pointer1 is (in a way) "referencing" array1. You can now use pointer1 and array1 almost interchangeably.

One major difference between using pointers and arrays is how their sizes are calculated: When you do sizeof on an array you get the size (in bytes) of the whole array. Assuming 32-bit int (the most common) then sizeof array1 will return 5 * 4 (or 20) as the size. If you get the size of a pointer, you get the size of the pointer itself, not what it might point to. So sizeof pointer1 will return either 4 or 8 (depending on if you're in a 32-bit or 64-bit system).

Going back to references, we can now change where pointer1 is pointing:

pointer1 = pointer2;  // Assuming pointer2 is unchanged, equivalent to pointer1 = array2

Now pointer1 and pointer2 are pointing to the same array, array2.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

In C# you can overload the = to copy the arrays. In C it is just simple assignment.

In C arrays decays to pointers for the sake of simplicity. In C *(array + N) == array[N] and *array == array[0]

  1. int array1 [5]; it is not the array of pointers only integers so *array1 = &array2; assigns array[0] with address of the first element of the the array2 converted to signed integer which generally doesn't make too much sense and it does not copy array2 to array
  2. To copy array you need to use memcpy or the loop to copy the element. You need to make sure that the destination array is large enough to accommodate the second array. C will not change the destination array size.
0___________
  • 60,014
  • 4
  • 34
  • 74
0

The assignments that your are doing is wrong. Basically a pointer points to a block of memory. from your code I can understand that array1 = array2; and *array1 = &array2; is wrong.

Syntax in C is something like this data-type* pointer-variable = (data-type*)malloc(no. of bytes you want);

See consider you want 10 block of memory of type int

int *p = (int *)malloc(10 * sizeof(int))

sizeof(int) return 4 bytes. Now p points to 10 * 4 = 40 bytes of memory, I multiplied by 4 because int is usually of 4 bytes and double is of 8 bytes and so on. Follow this link to understand C - Data Types

Now regarding changing pointers refer below example and read the comments

int *q = NULL // declare a pointer of same type as the block of memory it is going to point
q = p; //now q and p point same memory of 40 bytes, means value at q[0] is equal to p[0]

When you have an integer pointer and you increment it by p++ it will point to next memory location p[1], pointer will be exactly incremented by 4 bytes as int size is 4 bytes and for double it will be 8 bytes, for char it will be 1 byte and so on.

enter image description here

Now if you want to increase the size of dynamically allocated memory you can use realloc please follow this link to understand more. Dynamic Memory Allocation in C

int *p = NULL; 
// Dynamically allocate memory using malloc()
p = (int*)malloc(no. of bytes, sizeof(int)); 
// Dynamically re-allocate memory using realloc() 
p = realloc(p, (no. of bytes) * sizeof(int)); 
// Avoid memory leaks
free(p);

Realloc working principal


Syntax in C++ is something like this data-type* pointer-variable = new data-type[size];

See consider you want 10 block of memory of type int

int *p = new int[10]

Just use new operator to allocate block of memory and use delete to free allocated memory to avoid memory leaks.follow this link new and delete operators in C++ for dynamic memory

Or If you are looking for containers where you don't know how much memory should be allocated the use standard template library vector, it helps creating dynamic arrays.follow this link Vector in C++ STL

Giriraj Pawar
  • 411
  • 5
  • 14
  • Some programmer dude has given wonderful explanation regarding C, if you want to know about C++ you can look into my answer. – Giriraj Pawar Jun 05 '20 at 07:32