int *n=(int *)5;//Valid
cout<<*n;//Invalid
Why pointer n can point to an address although 5 is not a memory location.
Why I can not print out the screen the value of n.
You are attempting to dereference memory address 0x5, which is probably restricted memory.
int *n=(int *)5;
You are casting the integer literal 5 as an int*. What that means is you are saying 0x5 is an address. When attempting to dereference that pointer with *n, you will get an error.
Instead, you would need to do something like:
int five = 5;
int *n = &five;
cout << *n;
Don't use (int *), use the address-of operator &. Also keep in mind you cannot take the address of a literal other than string literals.
Short answer: because the value of n is n. *n is the value at n: i.e., what it's pointing to.
If you want n to point to the value 5 rather than the address 5, you have to make it do so:
int x = 5;
int* n = &x;
Now n is the address of a stack location that has 5 as its value.
Related
I have this code and im stuck at second line
unsigned long check_password(const char* p){
int* ip = (int*)p;
int i;
int res=0;
for(i=0; i<5; i++){
res += ip[i];
}
return res;
}
int* ip = (int*)p; What does this line mean ?
int* ip = (int*)p; What does this line mean ?
It means, "create a pointer to integers which starts at the same address as p."
The function is expecting p to be pointing to a sequence of bytes that represents 5 integers.
The behaviour of this function is only defined if p really was pointing to a sequence of integers before being cast to a const char*
In practice, the author of this code is assuming:
That the sequence of bytes has been encoded in such a way that they truly represent 5 integers on this machine (taking into account word size and endian-ness of the architecture).
that the alignment of the address represented by p is correct for addressing memory as integers (some processors have restrictions in this regard).
It's probably not code you want to copy or learn from, other than as a cautionary tale.
unsigned long check_password(const char* p){
int* ip = (int*)p; // line 2, non-const not required
int i;
int res=0;
for(i=0; i<5; i++){
res += ip[i]; // line 6
}
return res;
}
Line 2 declares ip as a pointer to integer and initializes it to (int*)p. (int*)p is a C-style cast, which is in this case resolved to reinterpret_cast<int*>(const_cast<char*>(p)). See
When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?
ip now points to the memory location of p. When using ip, the memory at that location is interpreted as holding an integer, even though it holds a char; and it can be modified, even though it was initially declared const.
Line 6 treats ip as if it was pointing to the first element of an array of int and adds the ith element of that array to res. It's likely that ip actually points to the first element of an array of char. That means, that each iteration sizeof(int) consecutive elements of that array are interpreted as the representation of a single int.
The intention of this code is probably, that a sequence of 5 ints is passed as an array of char of length sizeof(int)*5.
Note that this code is UB if p doesn't actually point to memory of a size of at least sizeof(int)*5, since the memory in that region is read. I.e. the char-array must be at least of length sizeof(int)*5.
Casting away the const in your code is not required
unsigned long check_password(const char* p){
const int* ip = reinterpret_cast<const int*>(p);
int res = 0;
for (int i = 0; i < 5; ++i){
res += ip[i];
}
return res;
}
This question already has answers here:
How do I use arrays in C++?
(5 answers)
Closed 6 years ago.
C++
int arr[5] = {1, 2, 3, 4, 5};
int (*p)[5] = &arr;
I know p is a pointer which points to an array with 5 elements, but when I try to print the address:
cout << p << " " << *p << " " << &arr << endl;
It gives me:
0x7fff50c91930 0x7fff50c91930 0x7fff50c91930
Question:
How could p equals *p? And now that p equals to &arr, why *p != arr[0]? What exactly does the value p and *p hold?
It would be more clear to imagine that p points to the whole memory block of 5 int. So if there is a ( p + 1 ) it would point to the next memory block.
This then help answer your questions.
How could p equals *p?
p is pointer to array[5] that is initialized to point to arr[5]
*p is the value of the first array element - which is the address of arr[5]. And because the name of the array is the address of the first element. So when you print p and *p they are the same.
And now that p equals to &arr, why *p != arr[0]?
*p is the address of the first array element - which means the address of the whole arr[5] memory block. On the other hand, arr[0] is the first element of the array that p points to, so it's a real value (1) not an address.
What exactly does the value p and *p hold?
As your first question, both of them hold the address of the whole arr[5] memory block.
first of all
'int' this is int type
'int*' this is int pointer type
so
int arr[5] = {1, 2, 3, 4, 5};//declare and initialize array of five integers
int* p[5] ;//declare array of five integer pointers
pointers store only a reference. when we de-reference it by using * it gives the actual value stored at that reference.
int* is a type and only * is a operator(de-reference operator)
int (*p)[5] = &arr;// by doing this you are declaring array of five integer pointers and each pointer is initialing with starting reference of arr.
to get the values of arr by using integer pointer you can use
p[0][0]//1
p[0][1]//2
and so on
and same goes for pointers p[1], p[2] and so on
The name of an array usually evaluates to the address of the first element of the array, but there are two exceptions:
When the array name is an operand of sizeof.
When the array name is an operand of an unary & (address of).
In these 2 cases, the name refers to the array object itself.
The name of the array evaluates to the address of the array .
So arr evaluates to &arr.
But the types will be different.
Try this -
auto ar1 = arr;
auto ar2 = &arr;
auto ar3 = p;
auto ar4 = *p;
ar1 will be of type int*.
ar2 will be of type int(*)[5]
Here you can see that ar4 and ar1 are the same type and ar2 and ar3 are the same type.
How do you access/dereference with arrays in c++??
for example, if I have this code
int num[] = {0,1,2,3};
int *p = #
I thought p was point to the first element in num array?
For some reason, I get a compiler error.
I want to use pointers and increments to access and change the value that is pointing,
for example, p gets the address of the first variable in the int array num and if I increment p, I get the address of the second variable in the int array num.
Any tips would be appreciate it.
I thought p was point to the first element in num array?
No. int *p = # is wrong, since &num is not a pointer to an int, i.e. int*, but is actually a pointer to an array of ints, i.e. int (*) [4].
To get a pointer to the first element, you can use int *p = num;, or int *p = &num[0]; instead.
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).
Version 1:
int* work(int** pointer, int offset)
{
return *pointer + (offset/sizeof(int));
}
int main()
{
int** pointer = (int**) 0x4df73c;
int offset = 0xf4;
int* healthLowestPointer = work(pointer, offset);
while(true) {
*healthLowestPointer = 1000;
Sleep(250);
}
}
Version 2:
int* work(int* pointer, int offset)
{
return (int*) (*pointer + (offset/sizeof(int)));
}
int main()
{
int* pointer = (int*) 0x4df73c;
int offset = 0xf4;
int* healthLowestPointer = work(pointer, offset);
while(true) {
*healthLowestPointer = 1000;
Sleep(250);
}
}
Version 1 works correctly, but version 2 doesn't seem to. I don't understand why version 2 is broken. Isn't dereferencing a a double-level pointer the same thing as dereferencing a single-level pointer i.e. it grabs the value at the memory address the pointer contains?
How would I write a function that takes a n-level pointer as input, and returns a 1-level pointer by dereferencing the n-level pointer n-1 times?
They are very different things. An int** is a pointer to a pointer to an int. If you dereference it, you get an int*. An int* is a pointer to an int. If you dereference it, you get an int.
In the first example, you pass an int** with value 0x4df73c as the first argument to work. You then dereference this, which should give you an int*. That is, 0x4df73c is the address of an address and doing *pointer has gotten you the second addess. You then do pointer arithmetic with this int* by adding (offset/sizeof(int)), which works out how many ints there are with offset bytes. So when you add this value, your int* will move along to point at the int at that offset. You then return this int* and all is well.
In the second example, you pass 0x4df73c as an int*. You then dereference it, which gives you an int. Now the + doesn't do pointer arithmetic - it does integer arithmetic. (offset/sizeof(int)) will still give you the number of ints in offset bytes, but the arithmetic won't do what you want. It won't increase the value of the int by the appropriate amount.
Let's say an int is 4 bytes on your machine. When you have an int* called p and you do p + 5, this doesn't just add 5 to the address in p. It adds 5 times the size of an int (20 bytes), so that it's now pointing at the 5th int. However, if you have an int called i and you do i + 5, this really does just add 5.
So that's your problem. When you add to the int, you're not doing the appropriate arithmetic. I imagine it would work if you change it to, assuming an int* and an int are the same size on your system (as you say they are):
return (int*) (*pointer + offset);
but I do not recommend this. Don't use an int as though it were a pointer. The cast to the (int*) involves a reinterpret_cast and is horrible. Stick to your first code.
Pointer arithmetic and integer arithmetic are not the same thing.
Ignoring the issue of whether writing to the locations you are using is valid, consider the result of these:
int i=5;
int j=i+1; // now j==6
int* pi = &i; // let's say pi is 0x1000
int* pj = &i+1 // now pj is 0x1000 + (sizeof int)