I want to declare a new integer in the heap,
int *intPtr = (int*) malloc(sizeof(int));
How do I change the value of the space in the heap, to which *intPtr points to?
Thanks
Dereference intPtr:
*intPtr = 0;
First of all, you don't need to cast the result of malloc. malloc returns a void* and the void* is casted implicitly to any pointer (int*, char*, ...).
So :
int *intPtr = malloc(sizeof(int));
You can also write :
int *intPtr = malloc(sizeof *intPtr);
If you want to change the value pointed by intPtr, just use the dereference operator '*' like :
*intPtr = <new_value>
where is your new integer value.
Related
I create an array:
unsigned short* array = malloc(sizeof(unsigned short)*N);
Assign values to it:
for(i=0; i<N; i++){
array[i] = rand()%USHRT_MAX;
}
Cast it to a void* and pass it to a worker thread which will find the max value in the array:
pthread_create(&threads[0], NULL, findMax, (void*)&array);
Which looks like this:
void* findMax(void* arg){
int i = 0;
unsigned short max = 0;
unsigned short* table = (unsigned short*)arg;
for(i=0;i<N;i++){
if(table[i]> max){
max = table[i];
}
}
printf("Max: %d\n", max);
}
The issue is that the numbers assigned in the array are misformatted. For example with the N randomly generated numbers: 3664 50980 37495 12215 33721, this loop will interpret the numbers as following instead:
table[0] = 28680
table[1] = 2506
table[2] = 5
table[3] = 0
table[4] = 32736
With the 5 and 0 as recurring pattern on the 2nd and 3rd place in the array.
I'm clearly overstepping some memory boundries, what is happening here and how do I fix it?
Change:
(void*)&array
to this:
(void*)array
since void* findMax(void* arg) expects a pointer, and you were passing the address of the pointer.
A pointer variable is a variable declared with a derived type specifier.
It is still a variable and it still has an address.
The value on that address is an address of a variable of that type.
A "pointer type" usually refers to void* while short pointer to short* and so on. void pointers can point to any variable, but you will have to convert it to a pointer of a generic type, when using it, using type-casting,
therefore you only cast void* when you are converting it to something else.
So if you add ampersand (reference) operator to a pointer &ptr you are ultimately referencing to the address of the pointer variable. It can be useful if you want to "repoint" the pointer from within a function.
Your code can still succeed, but you will have to declare the arguments differently:
( foo(void** vp) )
And to access the variable it points to, you dereference the void**:
void* p = *vp;
I try use a pointer to a constant integer number in C:
void *p = NULL;
p = (int *) 1;
printf("p=%d\n", *(int *)p);
but I got a segment fault.....
I cannot figure out how a pointer to a constant number in C w/o declaring a variable.
You are not taking the pointer to a constant but you are converting the constant to a pointer. You should do something like:
const int one = 1;
const int *p;
p = &one;
You cannot however do something like:
p = &1;
since literal constants haven't a memory location.
*(int *)p
You are derefrencing p, which is a pointer that has a value of 1. It's unlikely to be a valid address, segmentation fault is not a surprise.
P.S: p is not a pointer to const integer, it has a value of a constant integer.
p = (int *) 1; does not set the pointer p to point to a memory location with value 1. This sets the value of the pointer to 1, i.e, sets the pointer to point to the memory location with address 1.
try this:
void *p = NULL;
const int num = 1;
p = (int*)(&num);
printf("p=%d\n", *((int *)p));
i understand this being pointer *();
but *((type *)type); is whats confusing me
I have tried to understand pointers but its confusing me.
int offset = *((int *)arg);
Let's break this down:
(int *)arg;
This takes arg and casts it to an int *. The result of this expression is, of course, an int *.
*((int *)arg);
We're now just dereferencing that int * we just came up with — the result is the integer that the pointer was pointing to.
int offset = *((int *)arg);
We assign that integer into offeset.
No multiplication is involved here.
This (int *)arg takes whatever type arg is and pretends it is a int *
This *((int *)arg) takes the above pointer and deferences it, returning an int
You are casting arg to a pointer to int which is then dereferenced.
Think of it this way:
void* arg;
int* ptr = (int*) arg;
int offset = *ptr;
It's a cast followed by a dereference. Basically, you're telling the compiler, "Trust me. I know that arg points to an int, so read the int it's pointing to, and put it into offset.
I have a question about C pointers. Because I was wondering if I could set pointers through functions.
I mean like this:
void initptr(int **ptr)
{
ptr = (int *) malloc(sizeof(ptr));
}
int main()
{
int *ptr;
initptr(ptr);
}
Let me know.
Yes this is possible in C, you're just missing a dereference and address of operator in your sample
void initptr(int **ptr)
{
*ptr = (int *) malloc(sizeof(int*));
}
int main()
{
int *ptr;
initptr(&ptr);
}
The deference operator in *ptr = ... converts the type of ptr from int** to int* thus making it compatible with the assignment. Note: the casting of malloc is uneedded here.
The address of operator in initptr(&ptr) reversely converts the type of ptr from int* to int** thus making it compatible with the argument slot.
EDIT
As B Mitch pointed out the malloc size needs updating as well. You appear to be allocating an int* value and hence want the size to be that of an int*.
I believe you want this:
*ptr = (int *) malloc(sizeof(**ptr));
yes, but you need dereference ptr in your function in order to change what it points to
e.g.
void initptr(int **ptr)
{
*ptr = ...
}
when you call the method write
initptr( &ptr );
ptr = (int *) malloc(sizeof(ptr));
You missed to dereference the pointer to pointer so that it can actually take a pointer.
*ptr = (int *) malloc(sizeof(ptr));
// * newly added.
And also call to initptr(ptr); is wrong.
void initptr(int **ptr) ;
The function has an pointer to pointer as an argument. So, the argument ptr needs to hold the address of a pointer. So, change it to -
int *ptr = NULL ; // Initialize pointers to NULL
initptr(&ptr); // Passing the pointers address
If I am given the address of a pointer, how do I get what the pointer points to?
You might mean:
/**
* #param pointer_to_pointer_to_int: the address of a pointer to an integer.
**/
void function_that_takes_pointer_to_pointer(int **pointer_to_pointer_to_int) {
int the_int = **pointer_to_pointer_to_int;
printf("The pointer points to %d\n", the_int);
}
Assuming it is a valid pointer, you can dereference it using the unary * operator:
int *ptr = ...;
int x;
x = *ptr;
The unary * operator.
int *ptr = malloc(sizeof(int));
*ptr = 45;
printf("address: %p, value: %d", ptr, *ptr);
The most common way to be given the address of a pointer is through a pointer to a pointer. If the value the pointer points to is an integer, the type of the address of the pointer is int **.
To get the pointer to the integer, you need to dereference the double pointer. Then you can dereference the integer pointer to get the integer value.
To dereference a pointer, use the * operator.
int **double_pointer = given;
int *int_pointer = *double_pointer;
int value = *int_pointer;
You can also chain the dereferences to do that on one line.
int **double_pointer = given;
int value = **double_pointer;
The unary * operator returns or sets the value at a memory location.
For example:
int val = 42;
int* ptr = &val;
assert(val == *ptr);
If you have the address of a pointer, you would write **pointerpointer.
Going off of RedX's comment, If you have a situation like
void foo(void *ptr)
{
...
}
where the value of ptr is a pointer to a pointer to int, for example, you could do something like
void foo(void *ptr)
{
int x = **((int **) ptr);
...
}
Basically, you cast ptr to int **, then double-dereference it.
If you don't know what the target type is ahead of time (e.g., the function is meant to handle pointers to multiple types), then you're going to have to figure out a way to encode that type information in a second argument and pass it to the function.
There are two possible answers to your question depending on whether the compiler has a clue about the data that's referred or not.
Declaring a pointer of type int *, char * or mytype * instructs the compiler that a later attempt to dereference it using the unary * operator must yield a result of int, char or mytype respectively.
In the other case you would normally store a pointer either in a void * (generic, untyped pointer) or in a uintptr_t (an unsigned int the same size of a pointer, but without pointer semantics). In such a case the compiler doesn't have a clue how to interpret the dereferencing operator, so you must explicitly cast such a pointer to another pointer type, and only then dereference it:
int x = 5;
void *p = &x; /* p now points to an int, but the compiler doesn't know it */
printf("%d\n", *((int *) p)); /* we know what we did and don't rely on the compiler */
printf("%d\n", *p); /* compile-time error, dereferencing has undefined semantics */
Note that in compiled, unmanaged languages like C there is no runtime information about what kind of data a pointer is pointing to, unlike languages like Java where you can use the instanceof operator to check what a reference is really pointing to at runtime.