I have an array of int pointers
int * arr[3];
If I want to define a pointer to arr, I can do the following:
int * (*p)[] = &arr;
However, in my code, I need to first declare that pointer:
int *(*p)[];
My question is, how to assign &arr to it after it has been declared. I have tried (*p)[] = &arr; but that didn't work.
You can simply do p = &arr.
Try here.
If you want to assign p to arr you simply have to do p = &arr;
this is because when you write p you basically are saying to C: this is the pointer to a array of pointers
So when you &arr you get the same type as & gives you the pointer to the variable next to it
Also beware that if you want the value of a variable inside a struct that its pointed to( ie struct something *a, where inside there int i) you put a -> (making it a a->integer;)
You should update the answer to the full extent
Related
To make a pointer to a whole array we proceed like that:
int arr[3] = {1,2,3};
int (*p)[3] = &arr;
How come i get an incompatibility error when trying to do the same with a 2D array?
int arr[3][3] = {{12,10,45}, {44,55,66}, {79,85,91}};
int (*p)[3] = &arr;
The problem here is &.
I'm sure this is a simple question that might have already been answered but i don't find any answer to this specific issue concerning the use of &.
In C, "pointer" is a category of types. To get a particular type, you have to specify what type of object the pointer points to.
Accordingly, the unary & does not generically compute a pointer. It creates a pointer to the type of its operand.
Similarly, in C, "array" is a category of types. To get a particular type, you have to specify the element type, the number of dimensions, and the sizes of at least the last n-1 dimensions.
Thus, with
int arr[3] = {1,2,3};
int (*p)[3] = &arr;
arr is defined as an array of 3 int, therefore
&arr has type pointer to array of 3 int (spelled int (*)[3] as a C type name), and
p is declared with that type
so everything is consistent.
How come i get an incompatibility error when trying to do the same with a 2D array?
Because your "the same" is not analogous.
With
int arr[3][3] = {{12,10,45}, {44,55,66}, {79,85,91}};
int (*p)[3] = &arr;
, arr has type array of 3 array of 3 int, and &arr has type pointer to array of 3 array of three int (a.k.a. int (*)[3][3]). This is not the same type that p has. The appropriate declaration of p for this version of arr would be
int (*p)[3][3] = &arr;
You've got p in the second example as a pointer to a 1D array, not a pointer to a 2D array. For that, you need the following:
int (*p)[3][3] = &arr;
arr has type int [3][3], so &arr has type int (*)[3][3]. So you can use:
int arr[3][3] = {{12,10,45}, {44,55,66}, {79,85,91}};
int (*p)[3][3] = &arr;
You can then access p as (*p)[i][j].
But it would be more typical to use:
int arr[3][3] = {{12,10,45}, {44,55,66}, {79,85,91}};
int (*p)[3] = arr;
In this case, int [3][3] is compatible with an int (*)[3] pointer, and you can use p[i][j] when accessing it.
An analogous situation exists with one-dimensional arrays. If you have int x[3], then the usual pointer type to use is int *p, in which case you would do p = x and access it as p[i].
But if you really want the extra level of indirection, you could use:
int (*p)[3] = &x;
Then instead of p[i], you would now need to use (*p)[i] when accessing it.
I understand this question has been asked before, but I can't quite narrow down what i've done wrong here
int* arr[2];
arr = (int (*)[2]) malloc(sizeof(int) * size);
why is visual studio telling me the expression must be a modifiable lvalue? I'm trying to create an array with a constant column size, since that will always be two, but the rows will vary.
arr is an array of pointers. You cannot assign anything to it once it is initialized. Since you are trying to set its value to be the return value of a call to malloc, you probably want it be a pointer to an array. In that case, use:
int (*arr)[2];
Also, don't cast the return value of malloc. See Do I cast the result of malloc?.
Use
int (*arr)[2];
arr = malloc(sizeof(*arr) * size);
// ^^^^^^^^^^^^ We are speculating this is what you need,
// not sizeof(int)
If you want arr to point to an array of 15 x 2 objects, you will need to use:
arr = malloc(sizeof(*arr) * 15);
you have an array of pointers.... that array can't be used as a pointer itself, only the array entries are pointers.
you need a pointer to pointers, int **, unless you are wanting an array of ints, then you just int* arr
Did you consider using a struct? Then the syntax is a little more straight forward.
#include <stdlib.h>
typedef struct Two Two;
struct Two{
int b[2];
};
int main(){
int size = 100;
Two* two = malloc(sizeof(Two)*size);
return 0;
}
I am trying to pass struct to thread. Unfortunatelty when it happens i can no longer use p[i][j]. I am getting error: subscripted value is neither array nor pointer nor vector
typedef struct MY_M {
int *p1;
int *p2;
} MY_M;
int *M1[r];
for (i=0; i<r; i++){
M1[i] = (int *)malloc(c * sizeof(int));}
pthread_t thread1;
struct MY_M *p = malloc(sizeof(struct MY_M));
p-> p1 = *M1;
p-> p1 = *M2;
int ret = pthread_create(&thread1,NULL,thread,(void*) p);
thread here:
void* thread(void* parameter )
{
MY_M **p = (MY_M*)parameter;
p->p1[0][0] = 5;
}
When i comment p[0][0] the program is working fine. Why it is not working? I would be grateful for any help.
I can't tell exactly what you are trying to accomplish here, but I can see a number of errors.
In the first place, you assign two values to p->p1. I assume this is probably a mistake and you meant to assign one value to p->p1 and another to p->p2. (And where did M2 come from?)
Second, int *M1[r]; will allocate r pointers to int on the stack, which means the array containing the buffers will become invalidated shortly after the function returns.
You are also dereferencing M1 during assignment, which means you are only pointing to the first buffer that you allocated. Again, I can't tell exactly what you are trying to do with that, so I don't know what to recommend.
p1 is also type int*, which means it contains the address of an int, so it can only be dereferenced once and will resolve to int. If you want to dereference it twice (p->p1[x][y]) it should be type int** or pointer to some other dereference-able type.
Also, you cast parameter to MY_M*, but then assign it to a variable of type MY_M**. That is not correct (in fact, isn't that giving you a compiler error?)
As far as I can tell, you are simply trying to allocate some structure that your thread will later have access to. If that is the case, the code would be something like this:
typedef struct MY_M {
int* p1;
int* p2;
} MY_M;
MY_M* p = (MY_M*)malloc( sizeof(MY_M) );
p->p1 = (int*)malloc( c * sizeof(int) );
p->p2 = (int*)malloc( c * sizeof(int) );
pthread_t thread1;
int ret = pthread_create(&thread1, NULL, thread, (void*)p);
thread here:
void* thread(void* parameter)
{
MY_M *p = (MY_M*)parameter;
p->p1[0] = 5;
}
Overall, it seems that you don't fully understand pointers properly. I can try to give a brief rundown, but do consult other guides and references to fully understand the concept.
First: a pointer is an address. So int* a = &b; means that a of type int* will contain b's address, and therefore it points to b. If you dereference a pointer, that means you take the address value that it holds and follow the address to its original source. So *a dereferences a, resolving to the value stored in b.
Array index syntax is equivalent to offset + dereferencing, so when you say p->p1[0][0], that is really equivalent to *((*(p->p1+0))+0), which dereferences the variable twice.
You can't dereference something that isn't a pointer (i.e., doesn't contain an address). That's why your int* can't be dereferenced twice. After dereferencing it once, it is now an int, which does not contain an address and cannot be dereferenced.
I hope this helps.
What you're actually using is an array of pointers (to arrays), rather than a proper 2D array -- though that isn't really a problem here. As for why it isn't working, you simply have the wrong type for p in your thread function -- it should be int ** rather than int *.
Pointer1 points to 5.
Pointer2 points to 3.
I want to multiply 5*3, but I only have the pointers. How would I do this in C?
Also, what does uint32_t *pointer mean when:
pointer[2] = {1, 2};
I do not know what is so hard for the answerers to understand about this question. It is obviously about dereferencing pointers.
This is how you display the contents of the pointer that it is pointing to:
#include <stdio.h>
int main(void)
{
int num1 = 5;
int num2 = 3;
int* num1_ptr = &num1;
int* num2_ptr - &num2;
int sum = *num1_ptr * *num2_ptr;
printf("%d\n", sum);
return 0;
}
*num1_ptr and *num2_ptr takes your pointers and references what the contents of that memory address.
I can't answer the first half of your question without more information, but uint32_t* pointer is simply a pointer to an unsigned 32-bit integer value (unsigned int and uint32_t are usually equivalent types, depending on your compiler).
If I see a declaration that simply reads uint32_t* pointer without more information I'm going to assume it's a pointer to a single value, and that using the indexing operator [n] on such a pointer is basically overflowing the single-element-sized buffer. However if the pointer is assigned the result from an array or buffer function (e.g. malloc, calloc, etc) then using the indexing operator is fine, however I would prefer to see uint32_t pointer[] used as the declaration as it makes it much easier to determine the developer's intent.
uint32_t *pointer is just a pointer with garbage value unless you point it to something.
pointer[0] = 1;
pointer[1] = 2;
is only valid if you have earlier pointed it to some array of type uint32_t with atleast size two or to a block containing uint32_ts defined using malloc as follows:
uint32_t *pointer;
pointer = (uint32_t*)malloc(sizeof(int*SIZE); //SIZE > 2 here
or
uint32_t array[10];
pointer = & array[0]; // also, pointer = array; would also work.
int main(void)
{
int variableA = 5;
int variableB = 3;
int* ptr1 = &variableA; // Pointer1 points to 5.
int* ptr2 = &variableB; // Pointer2 points to 3.
int answer;
answer = (*ptr1) * (*ptr2); // I want to multiply 5*3, but I only have the pointers.
// Answer gets set to [value stored at ptr1(5)] MultipliedBy [value stored at ptr2(3)]
}
Your misconception is that pointers do not refer to values, such as 5 and 3.
pointers refer to variables, such as variableA and variableB; those variables have values which can be accessed and changed via the pointer.But the pointer only refers to the variable, not directly to the value behind it.
I want to pass a pointer as a size element of an array
example:
void hello(int array1[how can i refer pointer "ptr" here][2])
{
// i want to access the array used in the main() here
printf("hi");
}
int main()
{
int c=5;
int *ptr=&c;
a[*ptr][2];
a[0][1]=0;
a[0][2]=4;
}
I apologize for not being clear with my question here , i want to access the array used in the main() function in my hello() function.
You will have to use the value pointed to by the pointer:
a[*ptr][2];
ptr is the address pointed to by the pointer not the value stored there. You use the dereference operator * to get the value.
Of course, ptr is not of type int, it's of type int * (integer pointer). An array subscript must be of type int.
Maybe what you want is a[*ptr][2].
You need to deference the pointer by using *ptr so
int c = 5;
int *ptr = &c;
a[*ptr][2];
otherwise you are not using the value of ptr you are using its address in memory which returns an error.
Use the dereference operator *:
a[*ptr][2];
The expression *ptr tells the compiler to use the value pointed to by ptr.
As for your updated question, that's not possible. But it's not needed either, as it's passed as a pointer anyway.
When declaring a function, this:
void foo(int a[5][5])
is the same as this:
void foo(int a[][2])
And also the same as this:
void foo(int (*a)[2])
It has pretty much been answered already, you can't call an adress in the array a[0x3950f2][2]
Always use the pointer* to get the position in the array a[*ptr][2] to get the expected value - in this case: a[*ptr][2] == a[5][2]. You may read this.
Edit to your updated question: You can't to this. You can use the pointer when you call the function or when using the variable in the function.
Your second edit:
void hello(int **array1)
{
// i want to access the array used in the main() here
printf ("hi");
a[0][0] = 24;
}
int main()
{
int c = 5;
int *ptr = &c;
int **a;
a[*ptr][2];
a[0][1] = 0;
a[0][2] = 4;
hello (a);
return 0;
}