I want the first item in array points to my int.
There are two cases (read x
as 0 < x < N
, where N
is number of void *
allocated to p
) :
CASE I: p[x]
pointers pointing to valid memory locations and use another pointer to make changes to the value of those memory locations.
CASE II: p[x]
pointers not pointing to valid memory locations and use another pointer to make p[x]
pointers pointing to some valid memory location.
Looks like you are confused between these two cases because you are allocating memory to p[x]
pointers and then trying to assign some other memory location to *p
(p[0]
) using some other pointer c
. With this, you end up leaking memory in your program because of not properly handling the allocated memory.
First I would like to point out couple of things in your code:
If you want void
pointers p[x]
to point to memory location which hold an int
value, you should do:
p[i] = (void *)malloc(sizeof (int));
From C11 Standard#6.2.5p19:
19 The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.
Now, lets discuss the CASE I and II in detail:
CASE I: p[x]
pointers pointing to valid memory locations and use another pointer to make changes to the value of those memory locations.
void **p;
p = malloc(2 * sizeof(void *));
if (NULL == p) {
fprintf (stderr, "Failed to allocate memory");
exit(EXIT_FAILURE);
}
for (int i = 0; i < 2; ++i) {
p[i] = malloc(sizeof (int));
if (NULL == p[i]) {
fprintf (stderr, "Failed to allocate memory");
exit(EXIT_FAILURE);
}
}
Now, the void
pointers p[x]
pointing to memory locations of type int
.
Assume, you want to assign value (or make changes) to p[0]
memory location using some other pointer:
void *c = *p; // or void *c = p[0];
int a = 5;
*(int *)c = a; // need to type cast c to the type of memory it will point to
printf ("%d\n", *(int *)*p); // or printf ("%d\n", *(int *)p[0]);
Once done with pointers, make sure free the allocated memory. Here, you need to free p[x]
pointers and then pointer p
.
CASE II: p[x]
pointers not pointing to valid memory locations and use another pointer to make p[x]
pointers pointing to some valid memory locations.
In this case, you don't need to allocate memory to p[x]
pointers.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
void **p;
p = malloc(2 * sizeof(void *));
if (NULL == p) {
fprintf (stderr, "Failed to allocate memory");
exit(EXIT_FAILURE);
}
void **c = p;
int *a = malloc(sizeof(int));
if (NULL == a) {
fprintf (stderr, "Failed to allocate memory");
exit(EXIT_FAILURE);
}
*a = 5;
*c = a;
printf ("p: %p\n", (void *)p);
printf ("c: %p\n", (void *)c);
printf ("a: %p\n", (void *)a);
printf ("*c: %p\n", (void *)*c);
printf ("*p: %p\n", (void *)*p);
printf ("%d\n", *(int *)*p);
free(a);
free(p);
return 0;
}
Output:
p: 0x7fe603c05710
c: 0x7fe603c05710
a: 0x7fe603c05720
*c: 0x7fe603c05720
*p: 0x7fe603c05720 // *p pointer is pointing to memory location allocated to pointer a
5
Note: Whether to type cast malloc
result or not is opinion based. So, whatever you choose is up to you but make sure to be consistent everywhere in the code that you write.