Accessing the value pointed by a pointer - c++

Edit: This question should be considered abandoned. I have flagged this question for deletion as i do not know how to even proceed any more at this point. I thank all of you for your willingness and taking the time out of your day to help me.
I am reading and following the documentation at cplusplus on data structures. I have been trying to figure out why the compiler will not accept " *pfruit.weight; " on my own for hours. It am sure it is something simple that i am missing.
error C2228: left of '.weight' must have class/struct/union
1> type is 'product *'
1> did you intend to use '->' instead?
"The operand to the left of the period (.) is not a class, structure, or union."
So how do i correctly access the value pointed by a pointer member?(Not access a reference)
#include <iostream>
using namespace std;
struct product
{
int weight;
float price;
} ;
int main ()
{
product afruit;
product * pfruit;
pfruit = &afruit;
pfruit->weight;
//Access a member of an object to which we have a reference
//equivalent to: (*pfruit).weight
*pfruit.weight; //<------ I am so sorry, i meant This is the problem, i am using a reworded line of code from an example and it isn't compiling and returning the error.
//Access the value pointed by a pointer member called weight;
//equivalent to: *(pfruit.weight)
system("pause");
return 0;
}

This code
struct product
{
int weight;
float price;
} ;
int main ()
{
product * pfruit;
*pfruit.weight;
is an operator precedence error. The rules of C++ are that . has higher precedence than *. *pfruit.weight would be correct if pfruit was a struct and weight was a pointer, but in your code it's the other way around, pfruit is the pointer and weight is just an int. So you need to add brackets to apply the operators the right way around
(*pfruit).weight;

You may use the following statement :
(*pfruit).weight;
Instead of :
*pfruit.weight;
which evaluates at compile-time to the following because of operator precedence :
*(pfruit.weight)
This is wrong because you are dereferencing a non-pointer value and trying
to dereference a pointer with the . operator instead of ->.
EDIT :
Here's some piece of response and informations about pointers and to your question as I understood it.
#include <iostream>
using namespace std;
struct product
{
int *weight;
float price;
};
int main()
{
product afruit;
product *pfruit;
pfruit = &afruit;
// Allocating 10 * sizeof(int) bytes of memory. ptr will now point to the first sizeof(int) bytes
// of the memory pointed by the weight pointer.
pfruit->weight = new int[10];
// The first sizeof(int) bytes of the memory pointed by ptr (equivalent to *ptr) equals now the value 4.
pfruit->weight[0] = 4;
// The second sizeof(int) bytes of memory pointed by ptr (or (*ptr + 1)) equals now 42.
pfruit->weight[1] = 42;
// Dereferencing pfruit AND the pointer to the weight, thus returning the VALUE of the first sizeof(int) bytes of weight (4)
// instead of the value of the pointer to weight (0x8b4e008 for instance).
int value = *(pfruit->weight);
std::cout << "Value of pfruit->weight[0] = " << pfruit->weight[0] << std::endl
<< "Value of pfruit->weight[1] = " << pfruit->weight[1] << std::endl
<< "Value of *(pfruit->weight) = " << *(pfruit->weight) << std::endl
<< "Value of *(pfruit->weight + 1) = " << *(pfruit->weight + 1) << std::endl
<< "Value of ptr = " << std::hex << pfruit->weight << std::endl;
// Prints :
// Value of pfruit->weight[0] = 4
// Value of pfruit->weight[1] = 42
// Value of *(pfruit->weight) = 4
// Value of *(pfruit->weight + 1) = 42
// Value of ptr = 0x8b4e008
//
// Note that ptr[0] == *ptr and ptr[1] == (*ptr + 1)
return (0);
}

once try this u may get it this can be written as pfruit->weight or (*pfruit).weight
(*pfruit).weight;

product afruit;
product * pfruit;
pfruit = &afruit;
pfruit->weight;
pfruit is a pointer and has the address of the struct afruit.
We use pfruit->weight when we access struct members using a pointer .
When you use a struct name you use . operator.
Now, pfruit is the pointer . Therefore, the struct itself is *pfruit
*pfruit.weight;
This is interpreted as *(pfruit.weight), because .has higher precedence than *. and you can't use . operator with a pointer on LHS
You have to clearly show that you mean (*pfruit).weight

Bit late to the party, but try this:
It sounds like you are expecting values like 'int weight' to be stored as pointers to data somewhere else in the same way that the product is being referred to via pfruit. Some languages do do this, but in C++ simple data members like your weight and price are going to be stored actually in the product data structure. So, if afruit happens to exist at address 1000 in memory, then pfruit will have the value 1000:
... 1000 1001 1002 1003 ...
--+-----+-----+-----+-----+--
| afruit... | | |
--+-----+-----+-----+-----+--
^
|
pfruit = 1000
This means that your weight (int) and price (float) data members will be stored here, one after the other. (and since an int and float are typically 32 bits in size, i.e. 4 bytes, the memory looks like this:
... 1000 1001 1002 1003 1004 1005 1006 1007 ...
--+-----+-----+-----+-----+-----+-----+-----+-----+--
| afruit... |
| <------ weight -----> | <------ price ------> |
--+-----+-----+-----+-----+-----+-----+-----+-----+--
^
|
pfruit = 1000
Consequently, pfruit also happens to point at the weight data (because it's first in the structure), but the price data is 4 bytes further along.
So, when you say you want to get to the data 'pointed to by weight' it doesn't make sense because it actually turns out that you don't need to because when you access the weight member you are already referring to the weight value. It's right there, in the memory occupied by afruit.
If you ARE trying to get a pointer TO the weight (or cost) data itself (instead of afruit, or actually from pfruit) you can do something like this:
int* pweight = &afruit.weight; //from an actual product object
float* pcost = &pfruit->cost; //via a pointer to a product object
There are now various ways to access the members of the product structure afruit:
afruit.weight = 20; //directly access the structure member
pfruit->weight = 10; //follow the structure pointer
*pweight = 15; //derefernce the int pointer
I hope this helps someone, at least a little bit.
Sam

Related

C++ Why is the output of this code 3? (structs)

Can someone help me understand step-by-step why the following C++ code outputs a 3?
#include <iostream>
using namespace std;
struct sct
{
int t[2];
};
struct str
{
sct t[2];
};
int main() {
str t[2] = { {0,2,4,6}, {1,3,5,7} };
std::cout << t[1].t[0].t[1];
}
t[1] is {1,3,5,7}.
str is represented in memory as four integers back-to-back, organized into 2 sct structures. In this case, the first one has the values 1 and 3, while the second contains 5 and 7.
Thus, t[1].t[0] is {1,3}, so t[1].t[0].t[1] is 3.
str t[2] = { {0,2,4,6}, {1,3,5,7} };
This means we are an array of two str values {0,2,4,6} at 0 index and {1,3,5,7} at index 1.
cout<<t[0] //gives 0,2,4,6
cout<<t[1] //gives 1,3,5,7
Now, when in question cout << t[1].t[0].t[1]; we see what is in t[1] i.e (1,3,5,7), and with that we go inside the str block to assign t[1] to a variable of type stc. Inside it there, we find another variable t[2] of type stc. Here we divide our previous value as t[1].t[0]=1,3 and t[1].t[1]=5,7.
Now, when in question cout << t[1].t[0].t[1]; we see what is in t[1].t[0]=1,3, and with that we go inside the stc block to assign t[1].t[0] to a variable of type int. Inside it there, we find another variable t[2] of type int. Here we divide our previous value as t[1].t[0].t[0]=1 and t[1].t[0].t[1]=3.
Now, when in question cout << t[1].t[0].t[1]; we see what is in t[1].t[0].t[1]=3, and then it gets printed due to cout!!!!!

Whats the value of &y[0] == &x.a?

Got this piece of code from an homework assignment. I should figure out, what the value of &y[0] == &x.a. Btw sorry for not formatting properly, I tried my best.
So my approach was; y[0] = 1, and &y[0] means the address of 1, which is 0 in the array?
x.a confused me the most. Does it mean element a of the struct x? So x.a == 1 ? And its address would also be 0? So the boolean would come out as true(1), because 0 == 0. But the solution says it's false, but why?
struct my_struct {
int a;
double b;
int c;
};
my_struct x = { 1, 2, 3 };
int y[] = { 1, 2, 3 };
I expected the output 1 but apparently it's 0, but why?
&y[0] means the address of 1, which is 0 in the array
Almost, but not quite. The addresses given to you by the address-of operator are absolute values, not ones relative to the "container". So &y[0] is effectively the same as y, and &x.a is effectively the same as &x.
y is a value that can be converted to a pointer to the first element. This must and will be distinct (numerically) from &x which occupies a different part of memory.
| x.a | <- &x points here
| x.b |
| x.c |
| y[0]| <- y points here
| y[1]|
[ y[2]|
All of the above skims over the fact that those pointers might have different types. This matters to the compiler when checking the correctness of your code, but is ultimately discarded afterwards, as all addresses effectively become numerical values.
This expression
&y[0] == &x.a
compares addresses (pointers) of two different objects. The first one belongs to the array y (that is y[0] is the first element of the array) while the second one belongs to an object of the type my_struct (a is a data member of the object x).
The objects occupy different extents of memory.
So the expression yields false that is the addresses of the different objects are not equal each other.
I can provide an example when comparing two different pointers (that is pointers of different types) yields true.
Consider the following example
struct my_struct {
int a;
double b;
int c;
};
my_struct x = { 1, 2, 3 };
then ( void * )&x == ( void * )&x.a evaluates to 1.
Note: the casting is required because the operands have different types and there is no implicit conversion from one type to another.
One more example
#include <iostream>
#include <iomanip>
int main()
{
int y[] = { 1, 2, 3 };
std::cout << std::boolalpha
<< ( ( ( void * )&y == ( void * )y ) && ( ( void * )&y == ( void * )&y[0] ) && ( y == &y[0] ) )
<<'\n';
}
The program output is
true
All three expressions &y, y, and &y[0] have the same value (address). (An array used in an expression with rare exceptions is converted to pointer to its first element.)
The address of two separate declared variables are almost never equal (==).
Here, my_struct x = { 1, 2, 3 }; is declared separately from int y[] = { 1, 2, 3 };. When they're declared, they're given their own space in memory to occupy, so they're in two different spaces in memory. Even though the values stored by struct my_struct x and array int y[] are the same, they're stored in their own memory spaces.
If you want to see the actual memory locations, you can do this with a simple cout print statement:
cout << "&y[0]: " << &y[0] << endl;
cout << "&x.a: " << &x.a << endl;
&y[0] and &x.a are different addresses. If you are trying to check if they are the same, you can write a simple programm. And you will see the result.
struct my_struct {
int a;
double b;
int c;
};
int main()
{
my_struct x = { 1, 2, 3 };
int y[] = { 1, 2, 3 };
std::cout << "&y[0] = " << &y[0] << "\n&x.a = " << &x.a << "\n&y[0]==&x.a = " << (&y[0]==&x.a);
}
The output is:
&y[0] = 0x72261501a440
&x.a = 0x72261501a450
&y[0]==&x.a = 0
So we can see different values of &y[0] and &x.a. They are not the same. and also &y[0]==&x.a = 0 and it means false
The & will return memory address (depending on your target platform that is usually 16 to 64 bit number, either representing physical memory address, or virtual logical address mapped to physical memory by OS (on modern OS like linux or MacOS, the user process doesn't see true physical addresses by default)).
So this part of source:
my_struct x = { 1, 2, 3 };
int y[] = { 1, 2, 3 };
will instantiate both the structure and array in the memory as global variables, i.e. they will have memory addresses like 0x12345678, etc... and they will not overlap, if size of my_struct is for example 20 bytes, and x address is 0x1000, the array y will be in memory somewhere beyond it (address of y is also address of first element, in C/C++ the arrays are zero-cost abstraction, i.e. where the array starts, there's the first element already stored, and the rest of elements follow on consecutive memory addresses).
So your original expression &y[0] == &x.a is comparing one (absolute) address of particular element of the array with (absolute) address of structure member, and because they are instantiated in different regions of memory, the addresses will surely differ (as long as the index into array is within bounds) = false. You don't even need to check details which addresses precisely are compared.
But for completeness, the y[0] is the first element of array y, and address of that is identical to y itself. If there would be &y[1], that's address of second array element, with type int that means the &y[1] is equal to y+1 and/or to ((void*)y) + sizeof(int) ... in CPU machine code terms, that means if array starts at memory at address 0x2000, and int is 64 bits on your target platform, the second element starts at address 0x2008 (+8 bytes (64 bits) away from the start of array).
The &x.a is similarly full address where the actual value of member a resides in memory, so if the structure instance x starts at address 0x1000, the address of x.a will be also 0x1000 in this case (again zero cost of abstraction and it's simple struct type, if it would be class-like, having virtual functions, the member a would be probably a bit offset after the implicit virtual table pointer which is usually put at beginning of class/struct instance ... but this is implementation/platform specific, i.e. depends how particular compiler implements virtual functions/calls). For example the address of &x.b would be then 0x1008 (again I assume 64 bit int type, and I assume there's no extra padding applied in the my_struct, with different assumptions/conditions the offset of b from start of structure may be different than +8).
& gives you the address of an object.
&y gives you the address of the array y.
&y[0] gives you the address of the first element in array y which is equal to &y.
&x gives you the address of the struct x
&x.a gives you the address of the first member of the struct x which is equal to &x.
Since x and y are at different locations the addresses differ.

Turning a string into an int problems

So I have managed to convert the string into an int. However, in code #1, when I try to assign it to the first slot in the array and print it out, it prints '<'. Why is it doing this? I know it has something to do with ascii characters. Code #2 prints out the int 60 which is what I want.
atoi(menuAttributes[c].c_str()) = 20;
quantity[d] = 3;
string price[14];
#1
price[0] = atoi(menuAttributes[c].c_str()) * quantity[d];
cout << price[0] << endl;
#2
cout << atoi(menuAttributes[c].c_str()) * quantity[d] << endl;
Pretty much, I want price[0] to equal the int 60, not the char '<'. Thanks!
EDIT: Solved, thanks for everyones help. Noob here, apologies!
it's because of your price definition:
string price[14];
- you have defined it as an array of 14 strings, and attempting to assign to the first string in the array (price[0]) a numerical value (which is bogus from string's point of view).
Once you define your price as int price[14], then you'll get what you expect
price needs to be defined as an integer array. When you try to store the integer value 60 in price, it's implicitly converted to (char)60, which is < on the ASCII table.

what is the difference between *(arr+1)+1 and (*(arr+1))+1 in c++

I have recently been studying 2 D arrays at school in C++ and I have studied pointers as well. But this is confusing me.
#include<iostream>
#include<stdlib.h>
using namespace std;
int main()
{
system("cls");
char arr[][6]={"Name1","Name2"};
cout<<*(arr+1)+1<<endl;
cout<<(*(arr+1))+1<<endl;
system("pause");
}
And the output that I get is:
ame2
ame2
I have been taught that the * operator has a lower precedence than the + operator. Then why is *(arr+1)+1 and (*(arr+1))+1 giving the same output? Aren't they processed differently by C++?
No, the pointer dereference operator has higher priority than the addition operator, so *(arr+1)+1 and (*(arr+1))+1 are the same.
Well, many of my friends have asked me the same(or similar) questions as well. So here's what I do to solve such questions. Instead of calling '*' a dereferencing operator I call it an "value at address" operator.
writing name of an array gives us the base address of an array. So writing *(arr+1)+1
is actually value at address(arr + 1) + 1
Lets assume that arr is an integer array and starts at location 1000. That being said our equation resolves to value at address(1000 + 1) + 1
Now remember that incrementing a pointer is not same as incrementing an integer. Why?
int i=1000;
i++; //i will now be 1000 + 1
int *p=&i; //p points to 1000
p++; //p now points to 1000 + sizeof(int) ie 1000 + 4 = 1004
Getting back to where we were. value at address(1000 + 1) + 1 now resolves to value at address(1004) + 1, which further resolves to value at address 1008.
Try performing the same on (*(arr+1))+1, we get (value at address(1000+1)+1) which resolves to (value at address(1004)+1) which further resolves to (value at address(1008)), which is similar to our previous result. Now you can simply replace the entire fuss with whatever value the 1008 address has. Hope it helps. :)

Questions about pointers and what is/is not a pointer

Questions regarding, well, ultimately pointers to pointers (I suspect). Please read the questions posed in the commented code:
void doodah(char* a);
int main() {
char d[] = "message"; // one way of assigning a string.
// char* d = "message"; // another way of assigning a string, but REM'ed out for now.
cout << d << endl; // d appears not to be a pointer because cout outputs "message", and not an address. Why is this?
doodah(d); // a function call.
}
void doodah(char* a) {
cout << a << endl; // this outputs "message" - but why?! What does 'a' mean in this context?
// cout << *a << endl; // this outputs "m" - but why?! REM'ed out for now.
}
I am utterly confused! Please help.
cout knows how to output strings when given a char *. It does not attempt to print the pointer value itself.
An array is a bunch of objects next to each other somewhere in memory. The variable you've set the array to is actually secretly a pointer to the first item in that array (shhh!).
The biggest difference between char *c and char c[] is that the latter will be a const pointer, while the former is free to change. Also, C-Strings, like the one you have set there, are null terminated, meaning that the array ends in a binary 0 so things like cout will know when to stop iterating (this is also known as a one pass last).
For more information, you can read up on this question.
This is what the pointer a looks like in memory:
-------------------------------------------------------------
| | 'm' | 'e' | 's' | 's' | 'a' | 'g' | 'e' | '\0' |
| ^ |
| | |
| --- |
| |a| |
| --- |
-------------------------------------------------------------
a is a pointer to the first element of the string. When used in the stream inserter (operator<<()) the compiler will match it with the overload that takes a stream on its left hand side and a pointer to a character on its right hand side. It will then attempt to print every character until it reaches the null byte ('\0') by evaluating characters at incremental addresses from a.
The stream prints addresses through the overload that takes a void* on its righthand side. You can cast your pointer to a void* or use the standard-provided std::addressof() function as well:
std::cout << std::addressof(a);