I'm trying to understand this line of code. Can someone help me? Is it saving the result in the variable val or in the address of the variable val?
*((int*)(&val) +1)= A*(y) + (B - C)
Thank you
&val take the address of val
(int*)(&val) consider this address as a pointer to int
(int*)(&val) +1 increment this address by 1 (times sizeof(int))
*((int*)(&val) +1) = ... assign the right hand side value at this incremented address
It is interpreting val as if it was an array of integers, and storing the result of the right hand expression in its second element. To understand exactly the point of it all you should provide some more context (my guess: is it manipulating the raw content of double values?)
Notice that, depending on the type of val, this may be undefined behavior due to strict aliasing rules.
Divide expression *((int*)(&val) +1) into smaller ones to understand it:
take address of val (&val) and treat it as a pointer to an int (int *)
add 1 +1 to this pointer which means 'move pointer to next int' as it was an array of ints.
finaly by combining * and = apply right hand side expression to int pointed by pointer.
I hope others have answered your question. Adding to what others have said, the same code can be written as follows:
(int*)(&val)[1]= A*(y) + (B - C)
where (int*) will type cast &val as an implicit pointer to an integer which points to the address of val and [1] indicates the first integer location ahead of the location where val is stored.
This is how arrays are interpreted. Say you have an array
int a[10];
For this array, 'a' is a pointer which points to the base address ( address of the element a[0] ), and a[i] is nothing but *(a+i), i.e. the element which is i locations ahead of the first element of the array.
This is not correct code and you should never use it
Imagine this class:
class A {
int number = 10;
public:
void print(){ std::cout << number; }
};
The int number is private for the access not the use!
So how can we access this private int.
Simply:
A obj;
*( (int*) ( &obj ) ) = 100;
obj.print();
output
100
demo
Now if you would have more than one data then how to access?
by this syntax:
*((int*)(&val) +1)
It says:
find the address of the first data,
one index go ahead,
cast it to the int*,
then dereference it,
then initialize it
Related
This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 7 years ago.
I have a few questions. This isn't homework. I just want to understand better.
So if I have
int * b = &k;
Then k must be an integer, and b is a pointer to k's position in memory, correct?
What is the underlying "data type" of b? When I output it, it returns things like 0x22fe4c, which I assume is hexadecimal for memory position 2293324, correct?
Where exactly is memory position '2293324'? The "heap"? How can I output the values at, for example, memory positions 0, 1, 2, etc?
If I output *b, this is the same as outputting k directly, because * somehow means the value pointed to by b. But this seems different than the declaration of b, which was declared int * b = k, so if * means "value of" then doesn't mean this "declare b to the value of k? I know it doesn't but I still want to understand exactly what this means language wise.
If I output &b, this is actually returning the address of the pointer itself, and has nothing to do with k, correct?
I can also do int & a = k; which seems to be the same as doing int a = k;. Is it generally not necessary to use & in this way?
1- Yes.
2- There's no "underlying data type". It's a pointer to int. That's its nature. It's as data type as "int" or "char" for c/c++.
3- You shouldn't even try output values of memory which wasn't allocated by you. That's a segmentation fault. You can try by doing b-- (Which makes "b" point to the "int" before it actual position. At least, to what your program thinks it's an int.)
4- * with pointers is an operator. With any data type, it's another data type. It's like the = symbol. It has one meaning when you put == and another when you put =. The symbol doesn't necesarilly correlates with it meaning.
5- &b is the direction of b. It is related to k while b points to k. For example, if you do (**(&b)) you are making the value pointed by the value pointed by the direction of b. Which is k. If you didn't changed it, of course.
6- int & a = k means set the direction of a to the direction of k. a will be, for all means, k. If you do a=1, k will be 1. They will be both references to the same thing.
Open to corrections, of course. That's how I understand it.
In answer to your questions:
Yes, b is a pointer to k: It contains the address of k in the heap, but not the value of k itself.
The "data type" of b is an int: Essentially, this tells us that the address to which b points is the address of an int, but this has nothing to do with b itself: b is just an address to a variable.
Don't try to manually allocate memory to a specific address: Memory is allocated based of the size of the object once initialized, so memory addresses are spaced to leave room for objects to be allocated next to each other in the memory, thus manually changing this is a bad idea.
* In this case is a de-reference to b. As I've said, b is a memory address, but *b is what's at b's address. In this case, it's k, so manipulating *b is the same as manipulating k.
Correct, &b is the address of the pointer, which is distinct from both k and b itself.
Using int & a = k is creating a reference to k, which may be used as if it were k itself. This case is trivial, however, references are ideal for functions which need to alter the value of a variable which lies outside the scope of the function itself.
For instance:
void addThree(int& a) {
a += 3;
}
int main() {
int a = 3; //'a' has a value of 3
addThree(a); //adds three to 'a'
a += 2; //'a' now has a value of 8
return 0;
}
In the above case, addThree takes a reference to a, meaning that the value of int a in main() is manipulated directly by the function.
This would also work with a pointer:
void addThree(int* a) { //Takes a pointer to an integer
*a += 3; //Adds 3 to the int found at the pointer's address
}
int main() {
int a = 3; //'a' has a value of 3
addThree(&a); //Passes the address of 'a' to the addThree function
a += 2; //'a' now has a value of 8
return 0;
}
But not with a copy-constructed argument:
void addThree(int a) {
a += 3; //A new variable 'a' now a has value of 6.
}
int main() {
int a = 3; //'a' has a value of 3
addThree(a); //'a' still has a value of 3: The function won't change it
a += 2; //a now has a value of 5
return 0;
}
There are compliments of each other. * either declares a pointer or dereferences it. & either declares a (lvalue) reference or takes the address of an object or builtin type. So in many cases they work in tandem. To make a pointer of an object you need its address. To use a pointer as a value you dereference it.
3 - If k is a local variable, it's on the stack. If k is a static variable, it's in the data section of the program. The same applies to any variable, including b. A pointer would point to some location in the heap if new, malloc(), calloc(), ... , is used. A pointer would point to the stack if alloca() (or _alloca()) is used (alloca() is similar to using a local variable length array).
Example involving an array:
int array_of_5_integers[5];
int *ptr_to_int;
int (*ptr_to_array_of_5_integers)[5];
ptr_to_int = array_of_5_integers;
ptr_to_array_of_5_integers = &array_of_5_integers;
So I'm currently reading and learning a code from the internet (related to artificial neural network) and I found a part of the code that I don't understand why it works.
double* inputNeurons;
double* hiddenNeurons;
double* outputNeurons;
This is how it was declared. Then in this next code, it was changed and used as an array?
inputNeurons = new( double[in + 1] );
for ( int i=0; i < in; i++ ) inputNeurons[i] = 0;
inputNeurons[in] = -1; // 'in' is declared in the function as an int
So, I want to understand why and how it works. Did it become an array of "doubles"? If so, in what way can I also use this? Can this be used for struct or even class?
Every array can be treated as a pointer. But that does not mean every pointer is an array. Do not mix this up!
Assuming we have an array int test[..], the variable name also represents the address where the array is stored in the memory. So you could write
int * p = test;
At that moment my pointer p "becomes" an array, where "becomes" means 'points to an array'. Your example is similar - the only difference is that the memory is allocated dynamically (heap) and not on the stack (as in my example).
So how are the elements accessed?
Let's say, we want to get the first element (index 0).
We could say
int i = test[0];
or we could say
int i = *p;
Now we want to get the element at index 1:
int i = test[1];
Or - by using pointer arithmetics we could write
int i = *(p + 1);
In C++ (and C) pointers support indexing operator [] which basically adjusts the value of the pointer by the amount specified times the size of the type pointed.
So basically
inputNeurons[5] = 0;
is equivalent to
*(inputNeurons+5) = 0
Now this doesn't give you any guarantee about the fact that inputNeurons points to an address which is correctly allocated to store at least 6 double values but syntactically it is correct and well defined.
You are just adjusting an address to point to the i-th element of a given type starting from the specified address.
This means that
double x;
double* px = &x;
px[5] = 0;
Is syntactically correct although it is wrong, since px+5 is an address which points to memory which has not been reserved correctly to hold that value.
The pointer of type double (double* inputNeurons;) just gets assigned to point to the beginning of an dynamically allocated array (new( double[in + 1])) of the same type. It does not become an array.
You can do this with any other pointer and regular array of the same type. As a matter of fact an array is a pointer to specific address (to its beginning, i.e. to the element with index: 0).
When you increment the pointer by + 1, that one means 1 * type_size (i.e 1 * size_of_double)
In your case: inputNeurons points to the address of the first element of the array. If you dereference it: *inputNeurons, you will get the value stored at that address (if inputNeurons was an array, it would be equivalent to: inputNeurons[0] ). To access the next element just increment by one (*inputNeurons + 1).
when I work on pointers on a website I stick at a point.
When I write the given example I can assign adresses of array on a pointer for an increment a pointer example like ptr = arr; and it works correctly, but when I do the same thing for the decrement example it doesn't work it works only when I write like this ptr = &arr[2]. Why I have to write ampersand for decrement example? what is the difference between those two?
int main()
{
int arr[3]={10,20,30};
int *ptr,i;
ptr=arr;
for(i=0;i<3;i++)
{
printf("adress of variable arr[%d] %x\n",i+1,ptr);
printf("value of arr[%d] = %d\n",i+1,*ptr);
ptr++;
}
return 0;
}
You don't have to write it, just use the pointer:
ptr = var + 2 ;
for(i=0;i<3;i++)
{
printf("%d" , *ptr ) ;
ptr-- ;
Note that the last element is at +2 not +3.
in case of an int arr[3], &arr[0] and arr points to the same thing, the base address of the array, or, the address of the first element in the array. That's why in your increment case, you're allowed to write ptr = var which is nothing but storing the starting address in a separate pointer.
In case of decrements, there is nothing which can point directly to the end-of-array element address. So , you have to use the address-of-last-element [&arr[n-1], n being the size] to denote the address of the last element.
The difference is that in "decrement" case you use []. Think of arr as reference to whole array thus it is ok (compiler wise) to do ptr=arr or ptr=&arr with same result. On the other hand arr[3] is a reference to object in array, so you need to get its address explicitly (no compiler optimization for you).
What is the difference between the following declarations:
int* arr1[8];
int (*arr2)[8];
int *(arr3[8]);
What is the general rule for understanding more complex declarations?
int* arr[8]; // An array of int pointers.
int (*arr)[8]; // A pointer to an array of integers
The third one is same as the first.
The general rule is operator precedence. It can get even much more complex as function pointers come into the picture.
Use the cdecl program, as suggested by K&R.
$ cdecl
Type `help' or `?' for help
cdecl> explain int* arr1[8];
declare arr1 as array 8 of pointer to int
cdecl> explain int (*arr2)[8]
declare arr2 as pointer to array 8 of int
cdecl> explain int *(arr3[8])
declare arr3 as array 8 of pointer to int
cdecl>
It works the other way too.
cdecl> declare x as pointer to function(void) returning pointer to float
float *(*x)(void )
I don't know if it has an official name, but I call it the Right-Left Thingy(TM).
Start at the variable, then go right, and left, and right...and so on.
int* arr1[8];
arr1 is an array of 8 pointers to integers.
int (*arr2)[8];
arr2 is a pointer (the parenthesis block the right-left) to an array of 8 integers.
int *(arr3[8]);
arr3 is an array of 8 pointers to integers.
This should help you out with complex declarations.
int *a[4]; // Array of 4 pointers to int
int (*a)[4]; //a is a pointer to an integer array of size 4
int (*a[8])[5]; //a is an array of pointers to integer array of size 5
The answer for the last two can also be deducted from the golden rule in C:
Declaration follows use.
int (*arr2)[8];
What happens if you dereference arr2? You get an array of 8 integers.
int *(arr3[8]);
What happens if you take an element from arr3? You get a pointer to an integer.
This also helps when dealing with pointers to functions. To take sigjuice's example:
float *(*x)(void )
What happens when you dereference x? You get a function that you can call with no arguments. What happens when you call it? It will return a pointer to a float.
Operator precedence is always tricky, though. However, using parentheses can actually also be confusing because declaration follows use. At least, to me, intuitively arr2 looks like an array of 8 pointers to ints, but it is actually the other way around. Just takes some getting used to. Reason enough to always add a comment to these declarations, if you ask me :)
edit: example
By the way, I just stumbled across the following situation: a function that has a static matrix and that uses pointer arithmetic to see if the row pointer is out of bounds. Example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NUM_ELEM(ar) (sizeof(ar) / sizeof((ar)[0]))
int *
put_off(const int newrow[2])
{
static int mymatrix[3][2];
static int (*rowp)[2] = mymatrix;
int (* const border)[] = mymatrix + NUM_ELEM(mymatrix);
memcpy(rowp, newrow, sizeof(*rowp));
rowp += 1;
if (rowp == border) {
rowp = mymatrix;
}
return *rowp;
}
int
main(int argc, char *argv[])
{
int i = 0;
int row[2] = {0, 1};
int *rout;
for (i = 0; i < 6; i++) {
row[0] = i;
row[1] += i;
rout = put_off(row);
printf("%d (%p): [%d, %d]\n", i, (void *) rout, rout[0], rout[1]);
}
return 0;
}
Output:
0 (0x804a02c): [0, 0]
1 (0x804a034): [0, 0]
2 (0x804a024): [0, 1]
3 (0x804a02c): [1, 2]
4 (0x804a034): [2, 4]
5 (0x804a024): [3, 7]
Note that the value of border never changes, so the compiler can optimize that away. This is different from what you might initially want to use: const int (*border)[3]: that declares border as a pointer to an array of 3 integers that will not change value as long as the variable exists. However, that pointer may be pointed to any other such array at any time. We want that kind of behaviour for the argument, instead (because this function does not change any of those integers). Declaration follows use.
(p.s.: feel free to improve this sample!)
typedef int (*PointerToIntArray)[];
typedef int *ArrayOfIntPointers[];
As a rule of thumb, right unary operators (like [], (), etc) take preference over left ones. So, int *(*ptr)()[]; would be a pointer that points to a function that returns an array of pointers to int (get the right operators as soon as you can as you get out of the parenthesis)
I think we can use the simple rule ..
example int * (*ptr)()[];
start from ptr
" ptr is a pointer to "
go towards right ..its ")" now go left its a "("
come out go right "()" so
" to a function which takes no arguments " go left "and returns a pointer " go right "to
an array" go left " of integers "
Here's an interesting website that explains how to read complex types in C:
http://www.unixwiz.net/techtips/reading-cdecl.html
Here's how I interpret it:
int *something[n];
Note on precedence: array subscript operator ([]) has higher priority than
dereference operator (*).
So, here we will apply the [] before *, making the statement equivalent to:
int *(something[i]);
Note on how a declaration makes sense: int num means num is an int, int *ptr or int (*ptr) means, (value at ptr) is
an int, which makes ptr a pointer to int.
This can be read as, (value of the (value at ith index of the something)) is an integer. So, (value at the ith index of something) is an (integer pointer), which makes the something an array of integer pointers.
In the second one,
int (*something)[n];
To make sense out of this statement, you must be familiar with this fact:
Note on pointer representation of array: somethingElse[i] is equivalent to *(somethingElse + i)
So, replacing somethingElse with (*something), we get *(*something + i), which is an integer as per declaration. So, (*something) given us an array, which makes something equivalent to (pointer to an array).
I guess the second declaration is confusing to many. Here's an easy way to understand it.
Lets have an array of integers, i.e. int B[8].
Let's also have a variable A which points to B. Now, value at A is B, i.e. (*A) == B. Hence A points to an array of integers. In your question, arr is similar to A.
Similarly, in int* (*C) [8], C is a pointer to an array of pointers to integer.
int *arr1[5]
In this declaration, arr1 is an array of 5 pointers to integers.
Reason: Square brackets have higher precedence over * (dereferncing operator).
And in this type, number of rows are fixed (5 here), but number of columns is variable.
int (*arr2)[5]
In this declaration, arr2 is a pointer to an integer array of 5 elements.
Reason: Here, () brackets have higher precedence than [].
And in this type, number of rows is variable, but the number of columns is fixed (5 here).
In pointer to an integer if pointer is incremented then it goes next integer.
in array of pointer if pointer is incremented it jumps to next array
Hey guys Im trying to get down some theoretical stuff for Pointers and Arrays. I was hoping someone could reaffirm some suspicions I had with the concept of pointers and arrays.
Suppose I had something like this
int ia[] = {0,1,2,3,4,5};
ia[2]; // =2
int* ip = &ia[0]; // pointer ip gets the address of element 0 in array ia
ip[2]; // ??
ip[2] = 42; //
Most of this code is theoretical obviously but im a bit unsure of the last 2 lines. First off is saying ip[2] the same as saying ip now points to the 2ndth element in the array? Is it equivalent to saying *ip = ia[2] ?
Im also confused with the last line. ip[2] = 42; so the 2ndth element of the object that the ip points to, that address gets the value 42? Or is that an array notation method of dereferencing? Im just a bit confused on whats going on.
ia[n] is a different way of writing *(ia+n), therefore int* ip = &ia[0] is the same as int *ip = ia.
You are assigning ia to ip. That of course also makes ip[n] == ia[n] for all values of n.
The following creates an array called ia and stores the numbers in curly braces in the array:
int ia[] = {0,1,2,3,4,5};
The following in effect, does nothing:
ia[2];
However, if I take the above statement and change as follows, it assigns the value 2 to the integer t. This is because 2 is the third element in ia, and ia[2] references the third element in ia.
t = ia[2];
If your original declaration of ia had been
int ia[] = {0,1,15,3,4,5};
then you would be assigning t to 15.
The following changes the value at index 2 in ia to 42:
ip[2] = 42;
Now, ia consists of {0,1,42,3,4,5}.
This is because ia[2] is like saying *(ia + 2). If you assign ip to ia, then ip points to the first element of ia.
Similarly, ip[2] is like saying *(ip + 2). So, changing ip[2] will change ia[2], they reference the same chunk of memory.
When you write a[i] it is translated to *(a+i) where a is the base address (basically a pointer)
Also for arrays , base address is same as address of 1st element so address of a[0] is same as a [i.e a = &a[0]]
So, ip[2] = 42; translates to *(ip+2) = 42
Also, * gives value at that address ip[2] = 42 means *(ip+2) = 42 i.e value at location (ip+2)
a[b] is exactly the same as *(a + b). ALWAYS. So ia[2] is equivalent to *(ia + 2), and ip[2] is equivalent to *(ip + 2).
However, it is more subtle than that because ia and ip have very different types. ia is of array type; whereas ip is of pointer type. So they are not "the same" -- they are not even the same type of thing. It's like apples and oranges.
An array expression, used within certain contexts, can be implicitly converted to a pointer to its first element. If you wrote, int *ip = ia;, that would be such an implicit conversion -- ip now points to the first element of ia. It is the exact same as what you wrote, int *ip = &ia[0];
When you write something like *(ia + 2), again, in this context the array is also implicitly converted to a pointer to its first element, kind of like *(&ia[0] + 2). Since we know that ip points to the first element of ia, when you use ia in any context where it gets converted to a pointer, it's the same as using the value of ip. That's why ia[2] and ip[2] work the same.