Moving array pointer isn't changing ADDRESS of start - c++

My code:
#include <iostream>
using namespace std;
int main() {
char *test = (char*)malloc(sizeof(char)*9);
test = "testArry";
cout << &test << " | " << test << endl;
test++;
cout << &test << " | " << test << endl;
return 1;
}
Result:
004FF804 | testArry
004FF804 | estArry
I don't understand how it's possible that I had moved my array pointer and address didn't change.

The pointer did change. You're just not printing it. To print the pointer test:
cout << (void*) test << endl;
&test is the memory location where test is stored.
test is the value that you incremented with test++ (i.e., you didn't increment &test).
When you do cout << test the overload of operator<< that gets picked is one that takes a const char* and treats it as a C-style string, printing the characters it points to. The cast to void* avoids this behavior in order to print the actual value of test, instead of the value it points to.

In this statement
cout << &test << " | " << test << endl;
expression &test yields the address of the variable test itself that is evidently is not changed. It is the value stored in the variable was changed.
If you want to output the value of the variable test that is the value that points inside the string literal you should write
cout << ( void * )test << " | " << test << endl;
Take into account that there is a memory leak in the program because after allocating memory the pointer is reassigned. And sting literals have types of constant character arrays. So the pointer test should be declared like
const char *test;

Related

The actual and formal parameters of the array use the same block address, while the variables use different addresses

When using the address transfer of function, View address blocks of formal parameters and actual parameters, I find that the arguments and formal parameters of array share one address block, while the arguments and formal parameters of variables use two address block. What is the reason?
The code is as follows:
#include<iostream>
using namespace std;
void test(int *i,int * arr) {
cout << &i << endl;
cout << arr << endl;
}
int main() {
int i = 1, arr[2] = {1,2};
cout << &i << endl;
test(&i, arr);
cout << arr << endl;
system("pause");
return 0;
}
And this is the output:
0000008986B6FC54
0000008986B6FC30
0000008986B6FC78 //Arrays use the same space
0000008986B6FC78
You are passing pointers to the functions. The value of the pointers are not modified, ie in the function they point to the same objects as they do in main.
However, you are not printing what you think you print:
void test(int *i,int * arr) {
cout << &i << endl;
cout << arr << endl;
}
The pointer i gets the parameter &i (the i from main). Hence printing i in main will yield the same value as printing i in test. However, you are printing the adress of i in the function not the value of it. If you change your code to:
void test(int *i,int * arr) {
cout << &i << endl;
cout << i << endl;
cout << arr << endl;
}
You will notice the difference. I suggest you to rename at least one of the is in your code, because using same name for different entities can and does cause confusion. The i in test holds the value of the address of the i in main. That does not mean that they are the same, but rather i in test has the same value as &i in main.
In short: &i == &i but you expect &(&i) to be the same as &i.
There is no difference between passing a pointer to the int or passing a pointer to the first element of the array. From the point of view of the function they are both just pointers to int.
Note that test prints the value of arr but the location of i.
In test, &i is the location of its argument i.
That argument's value is the location of the i in main.
You will see this if you print i instead of &i.
arr, on the other hand, is implicitly converted into a pointer to its first element, and you are both passing &arr[0] to test to print, and printing &arr[0] in main.
Here is the same thing with explicit conversions and without using a function:
int main() {
int i = 1, arr[2] = {1,2};
cout << &i << endl;
// Create the "argument"...
int *p = &i;
// These two lines are 'test'...
cout << &p << endl;
cout << &arr[0] << endl;
// and this is after the function call.
cout << &arr[0] << endl;
}

Pointer Syntax Within Condition

After a pointer is initialized, do you have to use the * dereference operator to call the pointer in a condition?
Example:
int main()
{
int var = 10;
int *ptr = &var;
if(ptr) // does this need to be if(*ptr) ???
{.......}
}
And can I have a short explanation as to why?
Thank you.
if (ptr)
check if the pointer is not Null but
if (*ptr)
check if the value it points to is not zero (in this example is 10)
So for checking the value you shoud add *.
It depends on what you want to do.
if(ptr) checks if the pointer value is nullptr or not. Note that this is shorthand for if(ptr != nullptr).
if(*ptr) checks if what the pointer points to is nullptr (or 0) - and in that case, since you dereference (follow) the pointer to answer the question, the pointer itself had better not be nullptr in that case.
First of all, a pointer is only a variable. However, there are different contexts in which you can use it.
As any other variable you can access the pointers content (which is the adress of the underlying memory) as follows:
int i = 1;
int * p = &i;
std::cout << p << std::endl
this would output the adress of i since this is what is stored in p
If you however want to access the content of the underlying memory (the value of i), you need to dereference the pointer first by using the * operator:
std::cout << *p << std::endl;
This would print the value of iso 1.
of course you can also access the pointer's adress (since the adress of i is a numeric value as well and needs to be stored somewhere too):
std::cout << &p << std::endl;
That would output the adress of p so the adress where the adress of i is stored :)
As a little example try to run this code:
#include <iostream>
int main() {
int i = 1;
int * p = &i;
std::cout << "Value of i(i): " << i << std::endl
<< "Adress of i(&i): " << &i << std::endl
<< "Value of p(p): " << p << std::endl
<< "Dereferenced p(*p): " << *p << std::endl
<< "Adress of p(&p): " << &p << std::endl
<< "Dereferenced adress of p(*(&p)): " << *(&p) << std::endl;
}

What is the relationship between an array and its address?

The following code:
#include<iostream>
int main (void) {
int lista[5] = {0,1,2,3,4};
std::cout << lista << std::endl;
std::cout << &lista << std::endl;
std::cout << lista+1 << std::endl;
std::cout << &lista+1 << std::endl;
std::cout << lista+2 << std::endl;
std::cout << &lista+2 << std::endl;
std::cout << lista+3 << std::endl;
std::cout << &lista+3 << std::endl;
return (0);
}
Outputs:
0x22ff20
0x22ff20
0x22ff24
0x22ff34
0x22ff28
0x22ff48
0x22ff2c
0x22ff5c
I understood that an array is another form to express a pointer, but we cannot change its address to point anywhere else after declaration. I also understood that an array has its value as the first position in memory. Therefore, 0x22ff20 in this example is the location of the array's starting position and the first variable is stored there.
What I did not understand is: why the other variables are not stored in sequence with the array address? I mean, why lista+1 is different from &lista+1. Should not they be the same?
In pointer arithmetic, types matter.
It's true that the value is the same for both lista and &lista, their types are different: lista (in the expression used in cout call) has type int* whereas &lista has type int (*)[5].
So when you add 1 to lista, it points to the "next" int. But &lista + 1 points to the location after 5 int's (which may not be a valid).
Answering the question as asked:
std::cout << &lista+1 << std::endl;
In this code you take the address of array lista and add 1 to obtained answer. Given the sizeof of the array is sizeof(int) * 5, which means when you increment a pointer to it by 1 you add sizeof(int) * 5 to the pointer address, you end up with a number you see.

variable value and its address using pointers in C++

I'm having some trouble understanding pointers. In the following code, I'm trying print the address of a variable in 2 ways-once using the address operator and then using pointers:
#include<iostream>
using namespace std;
int main (void)
{
int x = 10;
int *int_pointer;
int_pointer = &x;
cout << "x address=" << &x << endl;
cout << "x address w pointer=" << int_pointer << endl;
return 0;
}
x address = 0028FCC4
x address w pointer = 0028FCC4
This works as expected. But when I do the same thing but now using character type variable, I get some trash output:
#include<iostream>
using namespace std;
int main(void)
{
char c = 'Q';
char *char_pointer;
char_pointer = &c;
cout << "address using address operator=" << &c << endl;
cout << "address pointed by pointer=" << char_pointer << endl;
return 0;
}
address using address operator=Q╠╠╠╠£åbªp é
address pointed by pointer=Q╠╠╠╠£åbªp é
I have no idea why this is happening. Thanks in Advance.
The C++ library overloads the << operator for certain types. (char*) is one of them. Cout is trying to print a string, an array of characters terminated by a null character.
Just cast the pointer:
cout << "address pointed by pointer" << ( void* )char_pointer << endl;
or
cout << "address pointed by pointer" << static_cast<void*>(char_pointer) << endl;
The reason it prints out junky stuff is because your char does not have a null terminator which means the program will keep searching for one until, and in the process will print out whatever it finds. The text you see is ASCII but referenced by the address which the ostream is misinterpreting. To get the address held in memory, you could use implicit conversion or a static_cast. I prefer the latter:
cout << "address pointed by pointer=" << static_Cast<void*>(char_pointer) << endl;
Like 2501 said, in different wording, &c, since c is a char, equals a char *, so it's going to try to print until the new line character '\0' that is either implicitly or explicitly put in character arrays going to std::cout so the stream knows where the end of the character array is.
So, yeah use the (void *) like 2501 said.

Weird Pointer Address for Individual Struct Data Member

I observe some weird behavior today , the code is as follow :
The Code :
#include <iostream>
struct text
{
char c;
};
int main(void)
{
text experim = {'b'};
char * Cptr = &(experim.c);
std::cout << "The Value \t: " << *Cptr << std::endl ;
std::cout << "The Address \t: " << Cptr << std::endl ; //Print weird stuff
std::cout << "\n\n";
*Cptr = 'z'; //Attempt to change the value
std::cout << "The New Value \t: " << *Cptr <<std::endl ;
std::cout << "The Address \t: " << Cptr << std::endl ; //Weird address again
return 0;
}
The Question :
1.) The only question I have is why cout theAddress for the above code would come out some weird value ?
2.)Why I can still change the value of the member c by dereferenncing the pointer which has weird address ?
Thank you.
Consider fixing the code like this:
std::cout << "The Address \t: " << (void *)Cptr << std::endl ;
There's a std::ostream& operator<< (std::ostream& out, const char* s ); that takes a char* so you have to cast to void* to print an address, not a string it "points" to
I think the "weird" stuff shows up because cout thinks it's a cstring, i.e. a 0-terminated character array, so it doesn't print the address as you expected. And since your "string" isn't 0-terminated, all it can do is walk the memory until it encounters a 0. To sum it up, you're not actually printing the address.
Why I can still change the value of the member c by dereferenncing the
pointer which has weird address
The address isn't weird, as explained above. In your code Cptr points to a valid memory location and you can do pretty much anything you want with it.