I'm a little rusty on pointers so bear with me. I have declared an array of chars and a char* pointer which is set in the following manner:
char* memPointer = &mem_arr[0];
When I run the program, it looks like my starting address is 6E2D200C (this address is always the same for some reason. I'm not sure if this is right or not. Please let me know if I'm doing something wrong)
Then, at some point when the user requests some memory, I try to increment the pointer and print out the new address. But the address remains the same as mentioned above. Here is what i have tried with no success:
//*(memPointer += actualSize); //no change
//memPointer += actualSize; //no change
//*memPointer += actualSize;// no change
&memPointer += actualSize; //no change
actualSize is an int by the way. If there is any other information that I need to provide, please let me know. Thank you in advance!
In your comments you indicate that your code is along the liens of:
char mem_arr[] = "hello world";
char* memPointer = &mem_arr[0];
memPointer += actualSize;
printf("memPointer = %p\n", &memPointer);
This line
char* memPointer = &mem_arr[0];
says: Let there be a variable of type char* called memPointer and let it contain the address of the 1st element of mem_arr. After this line, the variable memPointer contains the address of mem_arr[0].
&memPointer expands to the address-of memPointer rather than the address that memPointer contains. memPointer is a named variable, and saying &memPointer evaluates to the address - location in memory - of that variable, not its value.
memPointer += actualSize;
printf("&mem_arr[0] = %p, memPointer = %p\n", &mem_arr[0], memPointer);
will set memPointer to point to the actualSizeth element of mem_arr, as your code appears to be trying to do.
The address of the pointer will not change, but the pointer may point to something else if you start to increment it:
char* x = "test";
// *x is now 't'
x++;
// *x is now 'e'
There's no meaningful way to manipulate the address of the pointer itself unless you're using a pointer to a pointer, like char** x.
Your remark about "when the user requests some memory" and implying you must manipulate the pointer seems to be based on flawed assumptions. If you're doing this C-style you'd use realloc() where you get a pointer to the new allocation back. If you're doing C++ properly you'd new some new memory, copy the contents over, and delete the old allocation.
Maybe you're confused getting the address of mempointer instead of the address that mempointer is pointing to
This code shows how the address that my_pointer is pointing to changes whenever i increase the pointer or i give him a new memory address, take a look:
int mem_arr[256];
int * my_pointer = &mem_arr[0];
// let's give some values to the array just
// for fun
for(int i = 0; i < 256; i++)
{
mem_arr[i] = 10 + (i * 10);
}
// print original value & address
std::cout << "Value 1: " << *my_pointer << " Address 1: " << my_pointer << std::endl;
// increase pointer (+4 bytes)
my_pointer++;
// print current value & address
std::cout << "Value 2: " << *my_pointer << " Address 2: " << my_pointer << std::endl;
// let's seek into the 8th element
// of the array
my_pointer = &mem_arr[8];
// and print current value & address once again
std::cout << "Value 3: " << *my_pointer << " Address 3: " << my_pointer << std::endl;
getchar();
my_pointer
by itself returns the address that my_pointer is pointing to, while
&my_pointer
returns the address where the pointer my_pointer is stored
Related
#include <iostream>
using namespace std;
int main() {
int* z = new int(9);
cout << "address: " << z << endl;
cout << "value: " << *z << endl;
cout << "referance: " << &z << endl;
return 0;
}
Looking at the cout values, I was expecting the address and reference to give the same address, but heres what the output is:
address: 0x7fc452c032a0
value: 9
referance: 0x7fff5191b8d8
Just curious about the reason for this, is the plain value(z) the address of the variable in the heap with a value of 9, where var(&z) is address of the pointer variable which is located in the stack?
Here is a visualization:
Is the
&z designates the adress of the pointer int * z where you store the allocated adress new int(9).
The pointer z and the value 9 are stored at two different locations in memory.
There is not any notion of reference here, only adresses.
Let me go through some of the basics first.
A variable is a name that is used to refer to some location in the memory, a location that holds a value with which we are working.
Using '&' in C/C++ we can get the address of the variable.
A pointer is a variable that stores the address of a variable. For instance, in the example you are referring to
int* z = new int(9);
variable z stores the address of the value 9 [new int(9)].
Now, finally this variable has to be stored at some location in the memory and this can be accessed using ampersand (&).
&z //gives the address of the pointer to value 9 (address of variable z).
This is the same way the pointers and pointers to a pointer (multi level pointers) works.
int* z;
Above statement implies a pointer variable of int type declaration.
int* z = new int();
Above statement implies an address is allocated to pointer variable of int type dynamically.
int* z = new int(9);
Above statement implies value 9 is stored in a dynamically allocated.
cout << "address: " << z << endl;
Above line of code tells the address of pointer variable z.
cout << "value: " << *z << endl;
Above line of code tells the value stored in the variable z.
cout << "referance: " << &z << endl;
Above line of code tells the dynamically created variable's address.
I ask you questions because there is something I don't understand while studying dynamic allocation in C++.
Can I delete "St" and use "ptr" instead if I move the address stored in St to another pointer "ptr" when the dynamically allocated memory is pointed by the St pointer?
If I delete the "St" dynamic allocation, can I move the address to another pointer and delete the "St" immediately because the allocated space does not disappear but disconnects the pointer "St" from the space?
Below is the code I was writing.
Student is a structure.
int main()
{
case 1:
{
Student* ptr = NULL;
Student* St = new Student[10];
ptr = St;
delete[] St;
St = NULL;
break;
}
case 2:`enter code here`
{
printdata(ptr);break;
}
}
Once you've called delete[] on the pointer you get back from new Student[10], the value of that pointer is indeterminate. Both St and ptr are exactly that, but you reassign St. (Since C++11, use nullptr rather than NULL.)
The behaviour of dereferencing the pointer you get back from new Student[10] following the delete[] is undefined.
You can’t use memory you just freed. Memory at that address might still be usable (event till program closes), but there is no guarantee and program might use it for something else.
Can I delete "St" and use "ptr" instead if I move the address stored
in St to another pointer "ptr" when the dynamically allocated memory
is pointed by the St pointer?
If St points toward your array, you can make ptr point toward it as well, but it is not a transfer. What you actually transfer is the adress of the object you are pointing to. The 2 pointers will point toward the same object.
If you delete the object with delete[] (you delete the object, not the pointer), then the 2 pointers will point toward nothing. So what you actually want to do here is make ptr point toward the same object, and then make St point toward null.
Student* ptr = NULL;
Student* St = new Student[10];
ptr = St;
St = NULL;
Edit : If it may help you understand, here is what you can display ...
int x = 4;
int* p = &x;
cout << "x = " << x << " value of x." << endl;
cout << "&x = " << &x << " adress of x." << endl;
cout << "*p = " << *p << " the value of what p points to." << endl;
cout << "p = " << p << " the actual value of p which is the adress of x." << endl;
#include <iostream>
using namespace std;
int main() {
int* z = new int(9);
cout << "address: " << z << endl;
cout << "value: " << *z << endl;
cout << "referance: " << &z << endl;
return 0;
}
Looking at the cout values, I was expecting the address and reference to give the same address, but heres what the output is:
address: 0x7fc452c032a0
value: 9
referance: 0x7fff5191b8d8
Just curious about the reason for this, is the plain value(z) the address of the variable in the heap with a value of 9, where var(&z) is address of the pointer variable which is located in the stack?
Here is a visualization:
Is the
&z designates the adress of the pointer int * z where you store the allocated adress new int(9).
The pointer z and the value 9 are stored at two different locations in memory.
There is not any notion of reference here, only adresses.
Let me go through some of the basics first.
A variable is a name that is used to refer to some location in the memory, a location that holds a value with which we are working.
Using '&' in C/C++ we can get the address of the variable.
A pointer is a variable that stores the address of a variable. For instance, in the example you are referring to
int* z = new int(9);
variable z stores the address of the value 9 [new int(9)].
Now, finally this variable has to be stored at some location in the memory and this can be accessed using ampersand (&).
&z //gives the address of the pointer to value 9 (address of variable z).
This is the same way the pointers and pointers to a pointer (multi level pointers) works.
int* z;
Above statement implies a pointer variable of int type declaration.
int* z = new int();
Above statement implies an address is allocated to pointer variable of int type dynamically.
int* z = new int(9);
Above statement implies value 9 is stored in a dynamically allocated.
cout << "address: " << z << endl;
Above line of code tells the address of pointer variable z.
cout << "value: " << *z << endl;
Above line of code tells the value stored in the variable z.
cout << "referance: " << &z << endl;
Above line of code tells the dynamically created variable's address.
How come when I increment a pointer and then dereference it I get a random number?
Here is my code:
#include <iostream>
using namespace std;
int main(){
int reference = 10;
int *health = &reference;
int *health1 = health;
cout << "Health Address: " << health <<
"\nHealth1 Address: " << health1 <<
"\nReference Address: " << &reference << endl;
health1++;
cout << "Health1 value after being incremented then dereferenced: " << *health1 << endl;
}
My output is:
Health Address: 0x7fff5e930a9c
Health1 Address: 0x7fff5e930a9c
Reference Address: 0x7fff5e930a9c.
Health1 value after being incremented then dereferenced: 197262882
I was expecting to get a 0 since the next value of the next memory address would be null, but that is not the case in this situation.
I was expecting to get a 0 since the next spot in memory would be null, but that is not the case in this situation.
Your expectation is wrong. After you have incremented your pointer, it is no longer pointing to the valid memory buffer. Dereferencing it invokes an undefined behavior.
After you increase the pointer, it points to the memory not allocated and initialized by your program, so it's not null as you expected.
Each time you run your program, you may get a random integer.
I think your misunderstanding comes from the fact that you expect the pointer to point at the address of the next element of an array:
int myarray[] = { 1, 2, 3, 4, 5 };
int* parray = myarray;
std::cout << *parray << std::endl;
parray++; // increment the pointer, now points at the address of number 2
std::cout << *parray << std::endl;
But since there is no array in your example the incremented pointer points at the next memory block. The size in bytes of the type it points to is added to the pointer. What value lies there is anyone's guess:
int myvalue = 10;
int* mypointer = &myvalue;
mypointer++;
Dereferencing such pointer is undefined behavior. When you exceed the memory allocated to your process you will not get a pointer null value or a dereferenced value of 0.
Suppose X is the value of a pointer T *p;.
If p is incremented then, p will point to address X + sizeof(T)
*p will then give you the value stored at address X + sizeof(T). Now depending upon the validity of address X + sizeof(T), you will get the result which can be Undefined Behavior in case X + sizeof(T) is invalid.
(*health1)++;
you need to dereference the pointer as this would increment the address itself and not the value it is pointing at.
When print a pointer without * or & shows an address, I don't know what is this address.
For example:
int *n;
int num = 10;
n = #
cout << n << endl; // Prints 0020F81C
cout << &n << endl; // Prints 0020f828
The result:
I know cout << &n << endl; to print the address of place in the memory.
But what about cout << n << endl; ?
n is referring to "&num", therefore it's the address to the place in memory where num is pointing to.
You've answered your own question. It is an address. The address in memory of whatever the pointer points to, or zero: in this case, the address of 'num'.
Your second 'cout' prints the address of the pointer itself.