Having this code:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5
int main()
{
//int (*ar)[10] = malloc(sizeof *ar * SIZE);
int *ar[10] = malloc(sizeof *ar * SIZE);
printf("%ld\n", sizeof *ar);
}
I got
a.c:8:19: error: invalid initializer
8 | int *ar[10] = malloc(sizeof *ar * SIZE);
|
Why is this pointer initialization uses "invalid initializer"? What is invalid here?
CodePudding user response:
You declared an array of 10 elements of the type int *
int *ar[10] = malloc(sizeof *ar * SIZE);
and trying to initialize the array with the expression malloc(sizeof *ar * SIZE)
. So the compiler issues the error message.
If you want to dynamically allocate an array with SIZE
elements of the type char[10]
then you need to write
int ( *ar )[10] = malloc( SIZE * sizeof( char[10] ) );
To make the declaration of the pointer simpler you could introduce a typedef declaration for the array of 10 elements. For example
typedef int TArray[10];
TArray *ar = malloc( SIZE * sizeof( TArray ) );
Pay attention to that you need to use the conversion specifier %zu
to output objects of the type size_t
(it is the type of the value returned by the operator sizeof
). For example
printf("%zu\n", sizeof *ar);
This call will output the value equal to 10 * sizeof( int )
. If the sizeof( int )
is equal to 4
then the outputted value will be 40
.
CodePudding user response:
Just like 3 (4*5)
is completely different than (3 4)*5
,
int *(x[10]); // int *x[10];
is completely different than
int (*x)[10];
The following creates an array of 10 pointers:
int *ar[10];
Arrays are initialized using { }
.[1] For example, you could use the following:
int *ar[10] = {
NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL
};
But in this case, you might use something like this:
int *ar[10];
for (int i=10; i--; ) {
ar[i] = malloc(sizeof(*ar));
*(ar[i]) = 0;
}
This produces the following:
--------------- sizeof( ar ) == sizeof( int * ) * 10
ar --->| 0 | sizeof( ar[0] ) == sizeof( int * )
--------------- | --------------- sizeof( *(ar[0]) ) == sizeof( int )
| -------
---------------
| -------
--------------- | ---------------
| | --->| 0 |
... ---------------
| |
---------------
The following creates a (single) pointer to an array of 10 pointers.
int (*p)[10];
It could be allocated as follows:
int (*p)[10] = malloc(sizeof(*p));
for (int i=10; i--; )
(*p)[i] = 0;
This produces the following:
p
--------------- --------------- sizeof( p ) == sizeof( int * )
| ----------->| 0 | sizeof( *p ) == sizeof( int * ) * 10
--------------- --------------- sizeof( (*p)[0] ) == sizeof( int )
| 0 |
---------------
| |
...
| |
---------------
Special case,
char s[] = "abc";
is a shorthand for
char s[] = { 'a', 'b', 'c', 0 };
CodePudding user response:
int *ar[10];
Is an array of 10 pointers to int
. You need a pointer (not array) to dynamically allocate memory for the referencceod object.
Depending on type of the pointer you can:
int *ar = malloc(sizeof *ar * SIZE); // space for SZIE integers
int **ar = malloc(sizeof *ar * SIZE); // space for SIZE pointer to integers
int (*ar)[10] = malloc(sizeof *ar * SIZE); // space for SIZE * 10 integers, but pointer type is array to 10 integers/
CodePudding user response:
Why is this pointer initialization uses "invalid initializer"? What is invalid here?
int *ar[10]
does not declare a pointer. It declares an array. Initializers for an array should be inside braces, { … }
, so malloc(sizeof *ar * SIZE)
is not valid to initialize an array.
Brackets, [ … ]
bind more tightly than the dereference operator, *
, so int *ar[10]
is int *(ar[10])
, making an array of pointers. To make a pointer to an array, you must use int (*ar)[10]
, as shown in your first declaration.
CodePudding user response:
you should use : Also you are using wrong syntex for sizeof.
// pointer to an array of five numbers
int (* ar)[10] = NULL;
#include <stdio.h>
#include <stdlib.h>
#define SIZE 5
int main(){
int *ar = malloc(sizeof(int) * SIZE);
printf("%ld", sizeof(ar));
return 0;
}