Constants and Pointers - c++

This is going to be a long-winded post, so I apologize in advance.. but trying to ask multiple questions with context:
So, I've been trying to learn C++, and I've been picking everything up fairly easily, but I make a habit of trying to do things alongside the tutorials in "slightly different ways", in order to ensure that I understand the functionality of the thing I'm learning.
I seem to have hit a mental roadblock regarding constants and their involvements with pointers.
In the previous section, I think I got a pretty solid grip on references, dereferences (and the difference between * when used for dereferences and pointers), and then wrote this code:
int a[5];
int * p;
p = a;
cout << "Select the value for the first item at address(" << &a[0] << ")" << nl;
cin >> *p;
p++;
cout << "Select the value for the second item at address(" << &a[1] << ")" << nl;
cin >> *p;
p++;
cout << "Select the value for the third item at address(" << &a[2] << ")" << nl;
cin >> *p;
p++;
cout << "Select the value for the fourth item at address(" << &a[3] << ")" << nl;
cin >> *p;
p++;
cout << "Select the value for the fifth item at address(" << &a[4] << ")" << nl;
cin >> *p;
for (int n=0;n<5;n++)
cout << a[n] << "(" << &a[n] << ")" << nl;
Now, I realize that this isn't necessarily the most "optimized" solution, ever.. but it worked, I was able to "write" into the array I had store on the memory, and display the changes. It was neat, and like I said.. I think I got a pretty good understanding of how these things worked.
..and then, I hit the next section, which used the example:
const char * terry = "hello";
to teach me, and I quote: "As in the case of arrays, the compiler allows the special case that we want to initialize the content at which the pointer points with constants at the same moment the pointer is declared" (this being on the cplusplus.com tutorial).
Anyway, to get to the point: in order to try and familiarize myself with it and the previous section, I tried writing:
const char * p = "Hello.";
for (int n=0;n<5;n++)
cout << p[n] << "(" << &p[n] << ")" << nl;
cout << nl;
..and this does not work. I essentially tried replicating my previous code (although without the writing aspect) in an attempt to be able to read the RAM-location of each character in this constant array, and I experimented with every possible combination of pointers, references, dereferences, etc.. but I just get a print out of the whole "Hello." array with &p.
How in the hell does one get the reference of a constant array? I think I understand the basic premise that I'm creating an array and immediately allocating it to memory, and then assigning a pointer (p) to the first block ("H")'s location.. but I can't seem to print the blocks out. I was able to get the location of the first block to print at one point (can't remember what code I used to do this) and tied it into the for loop, but even then.. it just ALWAYS printed the location of the first block, even when assigned to follow the [n] count.
I have no idea what I'm missing, here, or if I'm just trying to reach "over my head", but maybe I just don't understand the usage/point of creating an array without being able to location the memory assignment of each item within it..
This brings me to my next issue, though. How does one get the memory location of a char variable, whether constant or not? I have been having issues with this code, as well:
char const a = 100;
int * b = &a;
cout << a << nl << *b << nl;
cout << nl;
Obviously, this doesn't work.. because I can't assign b to the location of a, since they're different variables.. and obviously making a char pointer is silly, since it's just going to print messed up/null characters instead of the location (I checked this, obviously.. not just assuming).
I hope I'm just missing an option to use which may just be "more advanced" than where I'm currently at.. but if I'm not, I don't quite see the point in being able to access the block location of any type of variable/constant, if you can't access ALL of them due to restrictions of the type being used.
This problem is sorta what limits the third quoted code, too: the fact that I can't just assign a variable to hold the &p value, since it itself would have to be a char to be compatible.. which is pointless since char can't hold the eight-digit reference.

In
const char * p = "Hello.";
[...] cout << &p[n] [...]
&p[n] is a pointer to char, and cout::operator<< has an overload that takes a pointer to a char and prints a null-terminated string, that's probably why you're confused.

Related

c++ pointer and variable address switch of value, why?

I'm trying to modify a variable by a pointer, the problem is that they have the same address but the output is not right.
Here's the code:
int *ret;
int set = 56;
ret = (int *)&ret - 1;
*ret = 3;
cout << ret << endl << &set << endl << set <<endl;
The output is:
0x61ff08
0x61ff08
3
This look great, but what is really weird is that when I replace:
cout << ret << endl << &set << endl << set <<endl;
With this:
cout << ret << endl << set <<endl;
The output becomes:
0x61ff04
56
The pointer change of value and the set variable isn't modified though. It's like if I take out the &set of the cout the address pointed of the pointer exchange his address with the variable.
If I do this:
ret = (int *)&ret + 1; // instead of -1
The output becomes:
0x61ff0c
3
Can I have an explanation? I didn't find any documentation about this.
Can I have an explanation? I didn't find any documentation about this.
Main documentation in this case is C++ standard, though it is sometimes not to easy to find and comprehend information from there. So short version in your case - you can only subtract or add integers to a pointer when resulting pointer would point to an element in the same array or pointing to the fictitious element behind the last (in this case it is illegal to dereference your pointer). For this purpose single variable is treated like one element array (so for pointer to single variable you can basically only do pointer + 1). All other hacky tries to access variables through magic with pointer arithmetics are illegal and lead to Undefined Behavior.
Details about UB you can find here What exactly do "IB" and "UB" mean?
The answer was that the compiler is giving address by he's own way to the variable/pointers according to the code so the addresses can change, to fix this problem by only using addresses
instead of :ret = (int *)&ret - 1;
we can use :ret = (int *)ret - ((int)(ret - &set));
(i didn't want to use the basic ret = &set because i was trying to do it by manipulation only addresses)

Printing out the value of pointer to the first index of an char array

I'm new to C++ and is trying to learn the concept of pointer. When I tried to print out the value of pStart, I was expecting its value to be the address of text[0] in hexdecimal (e.g. something like 0x7fff509c5a88). However, the actual value printed out is abcdef.
Could someone explain it to me why this is the case? What parts am I missing?
char text[] = "abcdef";
char *pStart = &text[0];
cout << "value of pStart: " << pStart << endl;
Iostreams provide an overload that assumes a pointer to char points to a NUL-terminated (C-style) string, and prints out the string it points to.
To get the address itself to print out, cast it to a pointer to void instead:
cout << "value of pStsart: " << (void *)pStart << "\n";
Note that you don't really need pStart here at all though. The name of an array (usually, including this case) evaluates to the address of the beginning of the array, so you can just print it directly:
cout << "address of text: " << (void *)text << "\n";
Get out of the habit of using endl as well. It does things you almost certainly don't realize and almost never want.

Why this C++ code works the way it works?

# include <iostream>
using namespace std;
int main(void)
{
char *name = "Stack overflow";
cout << *&name << endl;
cout << &*name << endl; // I don't understand why this works
return 0;
}
I understand how the first "cout" statement works but unable to understand why and how the second one works.
& and * are opposite operations. The first one takes the address of the array (adding one level of indirection) and then dereferences it (removing one level of indirection). The second dereferences the pointer (removing one level of indirection) and then takes the address of the result (adding one). Either way, you get back to the same value.
Just like 4 / 2 * 2 is the same as 4 * 2 / 2, or just like taking a step back and then forward leaves you at the same place as taking a step forward and then backward.
To understand how the second statement works substitute it
cout << &*name << endl;
for
cout << &name[0] << endl;
because *name and name[0] are equivalent and return reference to (lvalue) the first character of the string literal pointed by name.
The last statement is equivalent to
cout << name << endl;

C++: Pointers outputs confusing me

So I have the following code:
cout << _userLoginName << endl;
cout << *_userLoginName << endl;
cout << (_userLoginName+1) << endl;
cout << *(_userLoginName+1) << endl;
the variable char * _userLoginName has been set equal to "smith". My question is simple: Why in the last lines of code do I get the following output?
smith // as from cout << _userLoginName << endl;
s // as from cout << *_userLoginName << endl;
mith // cout << (_userLoginName+1) << endl;
m // cout << *(_userLoginName+1) << endl;
I really did try reasoning the result but I cannot figure it out.
Thank you.
If you give cout1 a char *, it will try to print a string. If you give it a char, then it will print that single character.
_userLoginName and (_userLoginName+1) are of type char *; *_userLoginName and *(_userLoginName+1) are of type char.
1. Technically, "give std::operator<<(std::ostream &, T)".
Pull out a sheet of paper and draw a box with six cell with "smith" written into them:
+-+-+-+-+-+--+
|s|m|i|t|h|\0|
+-+-+-+-+-+--+
^ ^
| +- _userLoginName + 1
+- _userLoginName
Use your pen as your pointer '_userLoginName' and point it at the first cell. Derefencing the pointer (i.e. using *ptr for a pointer ptr) means looking at the content of the cell it points at. That is '*_userLoginName' shows into the content of the cell. Writing a pointer of type char* or char const* does something funny: it follows the pointer and writes the content of each cell it finds until it reaches a cell having the value \0.
This should explain the first to outputs. Now, ptr + 1 looks at the cell next to ptr, i.e. ptr + 1 is another pointer (pull out another pen if necessary) placed the next cell. It does just the same as above.
Consider the type of *_userLoginName—it is char.
Maybe you overlooked that * in this context dereferences the pointer?
Dereferencing a pointer (such as *_userLoginName) always returns the element the pointer is pointing at, in the case of a normal string the first character therein, which is then printed.
Adding n to a pointer (such as _userLoginName+1) increments the pointer by n steps, so if it pointed to the 0th element it will afterwards point to the nth element.
Combine the two to explain the fourth line.
The first cout is looking at the pointer userLoginName (char* and char[] are very very similar in c++). The cout will print all values in memory, treating them as chars, until it comes across a '\0' character, which terminates the string.
The second cout is looking at one memory element, that pointed to by userLoginName, or userLoginName[0].
The third cout is doing the same as the first, but the memory address starts 1 char later than userLoginName, as the pointer is of type char.
The final cout is the same as the second, but is userLoginName[1].
There are two separate overloads for operator<< at work here: One for char-pointers, and one for chars. The second one, for single characters, simply prints that one character. The first one, for char pointers, treats the pointer as the pointer to the first character in a null-terminated array of characters (a "string") and prints all those.
Combine this with the language syntax that a[i] is the same as *(a + i) for an array a, and you have:
cout << s; // prints all characters, starting at the first
cout << *s; // prints only the first character, equal to "cout << s[0];"
cout << s + 1; // prints all characters, starting at the second
cout << *(s+1); // prints only the second character, equal to "cout << s[1];"

Referencing elements from two-dimensional array with a single value

I am probably missing something fundamental, but i cannot find a solution to the following issue.
I have a two-dimensional array of some float elements and i am trying to find a way to be able to reference them by using only a single value.
Example:
float test[5][50];
test[3][25] = 34.67;
cout << test[3][25] << endl;
int id = 25;
cout << *test[id*5+3] << endl;
I am hoping to get same result from both cout. Instead my output looks like this:
34.67
Segmentation fault
What am I doing wrong?
Thanks!
Without testing, I think something like this might work. Note that C++ arrays are major->minor from left dimension to right dimension.
float test[5][50];
test[3][25] = 34.67;
cout << test[3][25] << endl;
int id = 25;
float* test2 = &test[0][0]
cout << test2[(3 * 50) + id] << endl;
test is a float[][] with 5 elements (each of which is a float[] with 50 elements), and you are referring to test[128]. Hence the seg fault.You need to convert from single index to subscript using integer division and mod:
cout << test[id/50][id%50] << endl;
You should assert(id/50<5); to make sure your index is within bounds.
The crash is because you are trying to read the contents of the element as a memory address
*test[id*5+3] means int address = test[id*5+3]; then read memory at address.
If that address is 0 or memory you don't own then it will crash.
Accessing a two-dimensional bitmap (image) with a single reference is often useful.
Use:
int image2D[dim2][dim1];
int *image1D = &image2D[0][0];
Now
image2D[i][j] == image1d[i*dim1+j]
I agree with the first comment, that you really shouldn't do it, but I'll answer anyway.
I think that if you try:
cout << test[id*5+3] << endl;
it should work. There is no need to dereference with *.