Question about the efficiency of using an array or individual variables

In summary, the conversation discusses the efficiency of using array A[10] versus individual variables B(0..9) in a program. The individual variables may be faster due to their one-step access, while the array requires additional steps to access the desired value. The conversation also touches on the limitations of declaring arrays with a constant size and the use of vector as a workaround. Finally, the conversation explains the difference in initialization between {1} and {1, 1, 1, 1, 1, 1, 1, 1, 1, 1} for an array of boolean values.
  • #141
I think I got it, I need to practice more though. This is the program using pointer to pointer:
C++:
#include <iostream>
using namespace std;

void getRNum(int**, int);//return a pointer from the functionint main()
{
    int size = 5;
    int*pNumber = NULL;//initiate a pointer number
    getRNum(&pNumber, size);//pass address of pNumber
    cout << " Back to main, pNumber = " << pNumber << "\n\n";
    cout << " The array pointed by pNumber = {";
    for (int count = 0; count < size-1; count++)// display the numbers
        cout << *(pNumber + count) << " ";
    cout << *(pNumber + size-1) << "}\n\n";
    delete[] pNumber;//free the memory of 5 element array number[5]
    return 0;
}
void getRNum(int** pArr, int num)//receive &pNumber the addresses of pNumber.
{
    int* Arr = NULL; // set pointer Arr to Null
    Arr = new int[num]; //request 5 elements of int of memory from computer pointed by Arr.
    *pArr = Arr;// *pArr = address of Arr[0].
    for (int count = 0; count < num; count++)// input 5 integers to Arr[0..4].
    {
        cout << " Enter number " << count + 1 << " = ";
        cin >> *(*pArr + count);//*pArr = address of Arr[0], pArr + elements = address of Arr[1...]
        cout << " In memory location of Arr: " << (Arr + count) << "\n\n";
    }
}
/*
Enter number 1 = 2
Enter number 1 = 2
 In memory location of Arr: 012B4D50

 Enter number 2 = 3
 In memory location of Arr: 012B4D54

 Enter number 3 = 4
 In memory location of Arr: 012B4D58

 Enter number 4 = 5
 In memory location of Arr: 012B4D5C

 Enter number 5 = 6
 In memory location of Arr: 012B4D60

 Back to main, pNumber = 012B4D50

 The array pointed by pNumber = {2 3 4 5 6}
*/

I copy the display from running the program. It ask for 5 integer, I put in 2, 3, 4, 5, 6. You can see the physical address for each element. I print out the address of Arr( same as Arr[0]), they when the function exit back to main, I printed out the content of pNumber. You can see both address match. So the pointer is PASSED back to main from the function.

Thanks
 
Technology news on Phys.org
  • #142
yungman said:
he pointer is PASSED back to main from the function.

More precisely, the function writes the pointer that new returns to the variable whose address is contained in the function parameter pArr. Since the caller passed the address of the pointer variable pNumber in that function parameter, that variable is what the function writes to.
 
  • #143
PeterDonis said:
More precisely, the function writes the pointer that new returns to the variable whose address is contained in the function parameter pArr. Since the caller passed the address of the pointer variable pNumber in that function parameter, that variable is what the function writes to.
Ha ha, I can barely bent my mind to this so far, I need to play with this more to get a better feel of this. I think I have enough for today. Believe me, I have been working on this. It's hard to to twist around the address point to an address and all that. This is the first time in all 9 chapters that is difficult to me, or somehow, I have a mental block on this.

I am going to try the other examples from the geeksforgeeks. They are quite good, hopefully I get a better feel going through more of this.
 
  • #144
yungman said:
It's hard to to twist around the address point to an address and all that.

There's a saying that the two hardest concepts in programming for people to wrap their minds around are pointers and recursion. So you're certainly not alone. Hang in there.
 
  • Like
Likes yungman
  • #145
Why this work:
C++:
#include <iostream>
using namespace std;
int main()
{
    int var = 23;
    int* ptr= &var;
    int* pptr = ptr;
    cout << " var = " << var << "  *ptr = " << *ptr << "  **pptr = " << *pptr << "\n\n";
    return 0;
}
BUT, this doesn't work?
C++:
#include <iostream>
using namespace std;
int main()
{
    int var = 23;
    int* ptr =&var;
    int* pptr;
    *pptr = ptr;// Error
    cout << " var = " << var << "  *ptr = " << *ptr << "  **pptr = " << *pptr << "\n\n";
    return 0;
}

Compile error Listing 7.2.jpg
that is int* pptr = ptr; in the first one works, but int* pptr; *pptr = ptr; in the second one doesn't.
 
  • #146
yungman said:
that is int* pptr = ptr; in the first one works, but int* pptr; *pptr = ptr; in the second one doesn't.

What does the error message say? What kind of clue does that give you?
 
  • #147
PeterDonis said:
What does the error message say? What kind of clue does that give you?
I posted the error message right under the program " cannot convert int* to int."

I understand ptr is an integer, *pptr is a pointer and it doesn't match. Thereby an error. But isn't the two say exact the same thing? I even try pptr=&ptr, obviously it doesn't work also. BUT no matter how you look at it, pptr is a pointer to the address of ptr.

For example, say the pointer ptr is located in physical address 0x00FF.

int *pptr = ptr means the pointer pptr is pointing to address 0x00FF.

int*pptr; creates a pointer pptr. Then I set the content *pptr = 0x00FF which is *pptr = 0x00FF.

This is where a lot of the confusion for me.
 
  • #148
Try to think about what's in memory. You have an int variable, var (which is occupying 4 bytes somewhere in memory). You have two pointer to an int variables, ptr and pptr (which each are occupying 8 bytes somewhere in memory assuming you have a 64 bit OS).

int * pptr; (on line 7) declares an uninitialized pointer to an int. Being uninitialized/unset, it has what you would call a garbage value (meaning you have no clue what bits might be there), and it probably doesn't happen to be a valid address. *pptr = ptr; (on line 8) de-references pptr (note this is another use of * that is different from what it means in line 6,7), in this case meaning it takes the random garbage value that happened to be there, considers it to be a memory address, follows it to the corresponding chunk of memory, where it assumes there is some allocated place for a 4 byte signed integer to be (int), and then it tries to store a memory address (8 bytes) there.
 
  • #149
yungman said:
BUT, this doesn't work?
C++:
#include <iostream>
using namespace std;
int main()
{
    int var = 23;
    int* ptr =&var;
    int* pptr;
    *pptr = ptr;// Error
    cout << " var = " << var << "  *ptr = " << *ptr << "  **pptr = " << *pptr << "\n\n";
    return 0;
}

Try to think about what's in the actual memory. Maybe work it out on paper.

You have an int variable, var (which is occupying 4 bytes somewhere in memory). You have two pointer to an int variables, ptr and pptr (which each are occupying 8 bytes somewhere in memory, assuming you have a 64 bit OS).

int * pptr; (on line 7) declares an uninitialized pointer to an int. Being uninitialized and unset, it has what you would call a garbage value (meaning you have no clue what bits might be there).

*pptr = ptr; (on line 8) dereferences pptr before assigning ptr, in this case meaning it takes the random garbage value that happened to be in those 8-bytes stored by pptr, considers it to contain the memory address of an int, follows it to the corresponding chunk of memory at that address, where it assumes there is some allocated place for a 4 byte signed integer to be, and then it tries to store the value of ptr (an 8 byte memory address) there. The types mismatch (int) vs (int*) and it finds it should throw an error. But if it did compile, it would be a memory corruption bug.

For example, you might have this in memory up to line 7:

bytes 1 - 4 : stores the value of var, which is 23
bytes 2 - 10 : stores the value of ptr, which is 1 (the address of var)
bytes 11-18 : stores the value of pptr, which is garbage (who knows what's there) but let's say it is 27
...
byte 27: some memory we don't know much about

Line 8 says: treat bytes 11:18 as if they encode an address to an int variable, go to that address and put the value of ptr (an int*) there. e.g. it is something like:

(int )(bytes 27-30) = (int*)(bytes 2-10)

In the first/correct version, the example goes like this:

bytes 1 - 4 : stores the value of var, which is 23
bytes 2 - 10 : stores the value of ptr, which is 1 (the address of var)
line 7 says: allocate an int * and store the value of ptr there. Then,
bytes 11-18 : stores the value of ptr, which is 1
 
Last edited:
  • #150
yungman said:
I understand ptr is an integer, *pptr is a pointer and it doesn't match.
No, this is the same mistake you made before.
Both ptr and pptr have the same type: pointer to int (despite the misleading name for pptr, whose name would suggest that it is supposed to be a pointer to a pointer to an int).
yungman said:
Thereby an error. But isn't the two say exact the same thing?
No.

To fix your 2nd example, just remove the * from line 8, the line you've commented as an error.
 
  • #151
yungman said:
I posted the error message right under the program

Yes, I know. I was trying to get you to actually read it and think about what it is telling you.

yungman said:
isn't the two say exact the same thing?

No.

int *ptr = &var; says "allocate a variable of type pointer to int and store the address of var there".

int *pptr = ptr; says "allocate a variable of type pointer to int and take the pointer that is already stored in the variable ptr and store it there as well".

int *pptr; *pptr = ptr; says "allocate a variable of type pointer to int; at the location the pointer stored in this variable points to, store the pointer that is already stored in the variable ptr".

See the difference?

Note that there are actually two things wrong with the last bit of code. Aside from the fact that it is mismatching types (you are trying to store a pointer in a variable of type int, since that is the type of variable that the pointer pptr points to), it is trying to store to an undefined location, since *pptr means "the int variable that pptr points to", but the pointer variable pptr doesn't point to any int variable yet.
 
  • Like
Likes yungman
  • #152
Jarvis323 said:
Try to think about what's in the actual memory. Maybe work it out on paper.

You have an int variable, var (which is occupying 4 bytes somewhere in memory). You have two pointer to an int variables, ptr and pptr (which each are occupying 8 bytes somewhere in memory, assuming you have a 64 bit OS).

int * pptr; (on line 7) declares an uninitialized pointer to an int. Being uninitialized and unset, it has what you would call a garbage value (meaning you have no clue what bits might be there).

*pptr = ptr; (on line 8) dereferences pptr before assigning ptr, in this case meaning it takes the random garbage value that happened to be in those 8-bytes stored by pptr, considers it to contain the memory address of an int, follows it to the corresponding chunk of memory at that address, where it assumes there is some allocated place for a 4 byte signed integer to be, and then it tries to store the value of ptr (an 8 byte memory address) there. The types mismatch (int) vs (int*) and it finds it should throw an error. But if it did compile, it would be a memory corruption bug.

For example, you might have this in memory up to line 7:

bytes 1 - 4 : stores the value of var, which is 23
bytes 2 - 10 : stores the value of ptr, which is 1 (the address of var)
bytes 11-18 : stores the value of pptr, which is garbage (who knows what's there) but let's say it is 27
...
byte 27: some memory we don't know much about

Line 8 says: treat bytes 11:18 as if they encode an address to an int variable, go to that address and put the value of ptr (an int*) there. e.g. it is something like:

(int )(bytes 27-30) = (int*)(bytes 2-10)

In the first/correct version, the example goes like this:

bytes 1 - 4 : stores the value of var, which is 23
bytes 2 - 10 : stores the value of ptr, which is 1 (the address of var)
line 7 says: allocate an int * and store the value of ptr there. Then,
bytes 11-18 : stores the value of ptr, which is 1
Thank you so much, I am still reading this, I'll be back.

I kept reading the word "dereferencing", what is this mean? I read in the book, but it never explain this.

In the sentence highlighted in RED above, int *pptr declare it's a pointer pointing to an integer. Then it is NOT TRUE that pptr pointing to ptr as ptr is an address that is 8 byte!

Bottom line is address is 8bytes, int is 4 bytes, trying to store address in the space of an int will bomb the computer, so compiler will flag error. I'll be back.
 
Last edited:
  • #153
yungman said:
Bottom line is address is 8bytes, int is 4 bytes

That's not the primary issue. The primary issue is that "int" and "pointer to int" are different types. The compiler would give an error even if the in-memory size of both types were the same.
 
  • Like
Likes yungman
  • #154
PeterDonis said:
That's not the primary issue. The primary issue is that "int" and "pointer to int" are different types. The compiler would give an error even if the in-memory size of both types were the same.
thanks, I am getting it...slowly.
 
  • #155
yungman said:
I kept reading the word "dereferencing", what is this mean?

If the variable pptr stores a pointer to an int variable, then *pptr means "the int that the pointer pptr points to". The general idea of "look at the thing the pointer points to" is called dereferencing.
 
  • Like
Likes yungman
  • #156
PeterDonis said:
If the variable pptr stores a pointer to an int variable, then *pptr means "the int that the pointer pptr points to". The general idea of "look at the thing the pointer points to" is called dereferencing.
Thanks so much. I guess the meaning WRONG so far, I took it some kind of "de-referencing" which is like "not" referencing. That really throw me off also. I'm glad I asked as the word kept coming up.

So it's NOT true that *pptr =ptr as ptr is 8bytes. int *pptr only declare it points to an integer that is 4 byte.

I am getting it.
 
  • #157
yungman said:
So it's NOT true that *pptr =ptr

It's "not true" in the sense that the compiler will give an error, yes.

yungman said:
as ptr is 8bytes. int *pptr only declare it points to an integer that is 4 byte.

No. The problem is not the different in-memory sizes. The problem is that "int" and "pointer to int" are different types. As I said before, the compiler would give an error even if the in-memory sizes of both types were the same. For example, if you were compiling 32-bit code instead of 64-bit code, the size of a pointer and the size of an int would both be 4 bytes, but you would still get the same compiler error if you tried to assign a pointer to an int variable.
 
  • #158
yungman said:
Thanks so much. I guess the meaning WRONG so far, I took it some kind of "de-referencing" which is like "not" referencing. That really throw me off also. I'm glad I asked as the word kept coming up.

So it's NOT true that *pptr =ptr as ptr is 8bytes. int *pptr only declare it points to an integer that is 4 byte.

I am getting it.
One of the main problems is that while pptr is a variable for storing an address, that variable in this case isn't storing an address, it's storing garbage. Then you dereference it...

Anyways, what you should have done for it to be the same as the first/correct version is just pptr=ptr on line 8.
 
  • #159
Jarvis323 said:
while pptr is a variable for storing an address, that variable in this case isn't storing an address, it's storing a garbage. Then you dereference it

Yes, that's the second problem I referred to in post #151. The first problem is the type mismatch--trying to store a pointer in a variable that is of type int.
 
  • #160
I think it would be a good idea for the OP to take a pause and think about what a high level languange like C++ is for, noting that what it is NOT for is facilitating direct addressing of memory locations in a particlar hardware configuration and runtime instance.

The reason we use high level languages is abstraction. Abstraction enables us to write programs that do complicated things that are easier to write, quicker to debug and cheaper to maintain. With an object-oriented language like C++ we have a particular model of abstraction into classes which exhibit encapsulation, inheritance and polymorphism. This is what you need to learn, not pointers.

Sometimes in C++ it is necessary to use pointers, [Edited: but as soon as we do that we are no longer] but if we use them when we don't have to we are not using the power of a high level language and our code becomes harder to write, harder to debug and more expensive to maintain. We therefore only use pointers as a last resort.

For example in the real world you should almost never see a function that initializes an array that is passed to it as a parameter; this would be implemented with the array as a member variable (property) of an object initialized by a member function (method) of the object's class. I am afraid you have wasted hours of your own, and other peoples', time trying to understand how to do something that is irrelevant.

It is unfathomable to me that you are contemplating 'learning' C++ by skipping the chapters of the book on the high-level features of the language. You would learn much more about HLLs if you had skipped the chapter on pointers and moved on to classes.

There is a an alternative version of Gaddis's book which does exactly that; it has the suffix 'early objects' which is a much better way to learn IMHO.
 
Last edited:
  • #161
pbuk said:
I think it would be a good idea for the OP to take a pause and think about what a high level languange like C++ is for, noting that what it is NOT for is facilitating direct addressing of memory locations in a particlar hardware configuration and runtime instance.

The reason we use high level languages is abstraction. Abstraction enables us to write programs that do complicated things that are easier to write, quicker to debug and cheaper to maintain. With an object-oriented language like C++ we have a particular model of abstraction into classes which exhibit encapsulation, inheritance and polymorphism. This is what you need to learn, not pointers.

Sometimes in C++ it is necessary to use pointers, but as soon as we do that we are no longer using the power of a high level language and our code becomes harder to write, harder to debug and more expensive to maintain. We therefore only use pointers as a last resort.

For example in the real world you should almost never see a function that initializes an array that is passed to it as a parameter; this would be implemented with the array as a member variable (property) of an object initialized by a member function (method) of the object's class. I am afraid you have wasted hours of your own, and other peoples', time trying to understand how to do something that is irrelevant.

It is unfathomable to me that you are contemplating 'learning' C++ by skipping the chapters of the book on the high-level features of the language. You would learn much more about HLLs if you had skipped the chapter on pointers and moved on to classes.

There is a an alternative version of Gaddis's book which does exactly that; it has the suffix 'early objects' which is a much better way to learn IMHO.
I don't know, I mean polymorphism requires using pointers in C++. Writing copy constructors and such usually requires dereferencing a pointer. Interfacing with C libraries requires using pointers. Any kind of data structures course would require using them heavily (implementing lists, trees, etc.)
 
Last edited:
  • Like
Likes pbuk
  • #162
Jarvis323 said:
I don't know, I mean polymorphism requires using pointers in C++. Writing copy constructors and such usually requires dereferencing a pointer. Interfacing with C libraries requires using pointers. Any kind of data structures course would require using them heavily (implementing lists, trees, etc.)
Perhaps I did rather overstate my case against the importance of pointers and I have edited it accordingly, however I stand by my point that they are relatively less important than the concepts of OOP.

Jarvis323 said:
polymorphism requires using pointers in C++.
C:
#include <iostream>

class Shape {
  public:
    virtual float area() =0;
};

class Square: public Shape {
  private:
  float _side = 0;
  public:
  // Constructor.
  Square(float side) {
    _side = side;
  }
  float area() {
    return _side * _side;
  }
};

class Triangle: public Shape {
  private:
    float _base;
    float _height;
  public:
  // Constructor.
  Triangle(float base, float height) {
    _base = base;
    _height = height;
  }
  float area() {
    return 0.5 * _base * _height;
  }
};

int main() {
  std::cout << Triangle(1, 1).area() << std::endl;
  std::cout << Square(1).area() << std::endl;
}

Jarvis323 said:
Writing copy constructors and such usually requires dereferencing a pointer.
Yes, but before you write a copy constructor you need to learn what a constructor is!

Jarvis323 said:
Interfacing with C libraries requires using pointers.
Yes, but not all C++ programs call C libraries.

Jarvis323 said:
Any kind of data structures course would require using them heavily (implementing lists, trees, etc.)
Yes, but I don't need to know how and why to implement a red-black tree to use std::map.
 
Last edited:
  • #163
pbuk said:
C:
#include <iostream>

class Shape {
  public:
    virtual float area() =0;
};

class Square: public Shape {
  private:
  float _side = 0;
  public:
  // Constructor.
  Square(float side) {
    _side = side;
  }
  float area() {
    return _side * _side;
  }
};

class Triangle: public Shape {
  private:
    float _base;
    float _height;
  public:
  // Constructor.
  Triangle(float base, float height) {
    _base = base;
    _height = height;
  }
  float area() {
    return 0.5 * _base * _height;
  }
};

int main() {
  std::cout << Triangle(1, 1).area() << std::endl;
  std::cout << Square(1).area() << std::endl;
}
I'm not sure you can really call this an example of using polymorphism? I was thinking more in terms of this type of functionality, which supports passing a Triangle or Square to the same function, storing them both in the same container, etc.
C:
int main() {
Triangle t(1,1);
Shape * t = &t;
  std::cout << t->area() << std::endl;
}
I get your point and agree about the importance of abstraction though. I still like The Structure and Interpretation of Computer Programs as an introductory programming book because of how well it teaches abstraction, even though the use of a functional language makes it difficult for beginners.

https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-4.html
 
Last edited:
  • #164
I totally forgot to mention, I also get now that it's not just the size like trying to store 8bytes address in a 4 bytes integer space. It's the type difference also.

Ha ha, I even try
long int var;
*pptr = var;

It gave me an error because the TYPE is wrong.

Regarding of whether pointers are useful or not, I am just follow one chapter at a time. I don't judge, I am not at the stage to give an opinion. Just learn in order of the chapters. I just know this is the first confusing chapter that I need to stop and think, the others are quite easy and straight forward including strings in chapter 10 that I studied quite a portion from the other book. Just a lot of new names.

I know that high level languages are more abstract. BUT in my opinion as a hardware design engineer, You can NEVER forget what the programs are running on. I don't know whether you guys ever play with programming FPGA which you might think it's very similar to other programming languages. Man! Will you be screwed (pardon for my language) having the idea of removing from hardware. In VHDL or AHDL, if you don't know hardware, don't even touch it even though it looks to be a higher level language. I put this very strongly because I was the one that had to go in and fix it.
 
  • Like
Likes PeterDonis
  • #165
I still have question
C++:
#include <iostream>
using namespace std;
void getRNum(int**);
int main()
{
    int x = 20;
    int* pNumber;
    pNumber = &x;
    cout << " Before getRNum, address of pNumber = " << &pNumber << "\n\n";
    getRNum(&pNumber);
    cout << "     Return from function, &pNumber = " << &pNumber << "       *pNumber = " << *pNumber << "\n\n";
    return 0;
}
void getRNum(int** pArr)
{
    int y = 10;
    int* ptr = &y;
    cout <<" Address of y = " << &y << "    Address of ptr = " << ptr << "    *ptr = " << *ptr << "     y = " << y << "\n\n";
    pArr = &ptr;
    cout << " *pArr = " << *pArr << "    Address of ptr = " << ptr << "\n\n";
    cout << " pArr = " << pArr;
}
Compile error Listing 7.2.jpg


I made a copy of the output. you can see the address of pArr did not pass back from function getRNum to main. also I printed out *pNumber in main, it still have the value of 20 from the original x, not the value of y = 10 in getRNum.

Is it because when exiting the function getRNum, all the address and y are destroyed? the reason one can pass pointer of array is because array is not passed to function, it's only the reference being passed and the array is not destroy after exiting from function.

Also, I put pptr=&ptr, but pptr is not equal to address of ptr which is 007FFC7C. Why?

Thanks
 
Last edited:
  • #166
yungman said:
the address of pArr did not pass back from function

That's right, because pArr is a local variable inside the function and never gets returned to the caller. So setting its value inside the function does nothing as far as the caller is concerned. If you want to write the value of some local variable into the variable that is pointed to by pArr, you have to put *pArr on the left side of the = in the statement.

You are still confused about what your code is actually doing, vs. what you apparently intend for your code to do. Previously, you wanted the getRNum function to write a pointer to an int into a pointer variable in main; to do that, you needed to pass a pointer to a pointer to an int as a parameter to getRNum.

Now, it appears that you want the getRNum function to write an int into an int variable in main. If that's all you want to do, you don't need the extra layer of pointers. You can just pass an int * parameter to getRNum, so its signature could be getRNum(int *pArr), and the function call could be getRNum(&x);, and inside getRNUm you would do *pArr = y, which writes the value of the local variable y into the int variable that is pointed to by pArr.
 
  • Like
Likes yungman
  • #167
yungman said:
Is it because when exiting the function getRNum, all the address and y are destroyed? the reason one can pass pointer of array is because array is not passed to function, it's only the reference being passed and the array is not destroy after exiting from function.
The y and ptr variables in getRNum() are local variables that are allocated on the stack -- they are created on entry to getRNum(), and are destroyed on exit from this function.

When a function takes an array parameter, what is being passed is the address of the first element of the array.

Because C++ functions can have pointer parameters or reference parameters, it's confusing to use the term "reference" in both situations.

yungman said:
Also, I put pptr=&ptr, but pptr is not equal to address of ptr which is 007FFC7C. Why?
I think Peter already answered your question, but there is no variable named pptr in your program.
 
  • Like
Likes yungman
  • #168
PeterDonis said:
Now, it appears that you want the getRNum function to write an int into an int variable in main. If that's all you want to do, you don't need the extra layer of pointers. You can just pass an int * parameter to getRNum, so its signature could be getRNum(int *pArr), and the function call could be getRNum(&x);, and inside getRNUm you would do *pArr = y, which writes the value of the local variable y into the int variable that is pointed to by pArr.
To elaborate on what @PeterDonis said, here's what he's talking about.
C++:
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

void getNum(int *);
int main()
{
    int num = 23;
    cout << "Before call to getNum(), var == " << num << endl;
    getNum(&num);    
    cout << "After call to getNum(), num == " << num << endl;    
}

void getNum(int * pVal)
{
    cout << "Enter an integer value: ";
    cin >> *pVal;
}
The argument of getNum() is the address of num in main(). The input statement in getNum() dereferences pVal, thereby storing the value that was entered into the memory location of num. The output statements in main() show the values of num before and after the call to getNum().

pVal is an address. By dereferencing pVal (i.e., by prepending an asterisk as in *pVal), we get read or write access to the address that pVal represents.
 
  • Like
Likes yungman
  • #169
PeterDonis said:
That's right, because pArr is a local variable inside the function and never gets returned to the caller. So setting its value inside the function does nothing as far as the caller is concerned. If you want to write the value of some local variable into the variable that is pointed to by pArr, you have to put *pArr on the left side of the = in the statement.

You are still confused about what your code is actually doing, vs. what you apparently intend for your code to do. Previously, you wanted the getRNum function to write a pointer to an int into a pointer variable in main; to do that, you needed to pass a pointer to a pointer to an int as a parameter to getRNum.

Now, it appears that you want the getRNum function to write an int into an int variable in main. If that's all you want to do, you don't need the extra layer of pointers. You can just pass an int * parameter to getRNum, so its signature could be getRNum(int *pArr), and the function call could be getRNum(&x);, and inside getRNUm you would do *pArr = y, which writes the value of the local variable y into the int variable that is pointed to by pArr.
Thanks for the reply, I am not confused, I just want to simplify the program and still get to my goal to pass pointer-to-pointer to the function. I just want to verify things.

I actually have a program exactly like what you describe, passing int* as parameter.
C++:
//Passing pointer to function
#include <iostream>
using namespace std;
void getRNum(int*);
int main()
{
    int x;
    int* pNumber;
    pNumber = &x;//initializing pNumber to some address
    cout << " address of x = " << &x << "   Before getRNum, pNumber = " << pNumber << " *pNumber = " << *pNumber << "\n\n";
    getRNum(pNumber);
    cout << " After getRNum, pNumber = " << pNumber << " *pNumber = " << *pNumber << "\n\n";
    return 0;
}
void getRNum(int* pArr)
{
    *pArr = 10;// assign *pArr = 10
    cout << " pArr = " << pArr << "\n\n";
}

This one is exactly what you describe. Yes, for pointer to integer, I don't need int **pptr at all.

It seems that int **pptr is only of limited use, mainly to pass an array from main to function and get the result back. Array is only an address like array Ar[size], Ar is the address of Ar[0]. So when you pass array to function, you really pass &Ar to the function. So if you want pointer to Ar, you have to use int**ptr = &Ar.
 
  • #170
Mark44 said:
To elaborate on what @PeterDonis said, here's what he's talking about.
C++:
#include <iostream>
using std::cout;
using std::cin;
using std::endl;

void getNum(int *);
int main()
{
    int num = 23;
    cout << "Before call to getNum(), var == " << num << endl;
    getNum(&num);   
    cout << "After call to getNum(), num == " << num << endl;   
}

void getNum(int * pVal)
{
    cout << "Enter an integer value: ";
    cin >> *pVal;
}
The argument of getNum() is the address of num in main(). The input statement in getNum() dereferences pVal, thereby storing the value that was entered into the memory location of num. The output statements in main() show the values of num before and after the call to getNum().

pVal is an address. By dereferencing pVal (i.e., by prepending an asterisk as in *pVal), we get read or write access to the address that pVal represents.
Thank you, I understand now. The difference between yours and my program is you actually pass &num( address of num) to the function. You use the local pointer pVal to change the value of num, which, is in main. So even after exiting getNum function, pVal is destroyed, the change in the content of num still there.

In my case, I try to pass pointer from getNum back to main. But when getNum is closed, pointer is destroy and so is the value of y. So nothing is changed.

thanks.
 
  • #171
It is funny, I have been struggling with the pointers and pointer to pointer for over a day, I was so confused. BUT all of a sudden after going through the response here slowly, it is like crystal clear to me!
1) That you can ONLY assign the SAME TYPE of values to the pointers, that is you can ONLY assign ADDRESS of variable/constant to a pointer eg. int *ptr; ptr = &var; where var can be int, double, const, char etc.

2) You can ONLY assign address of a POINTER to int**pptr, not even an address of variables. eg. int**pptr; pptr = &ptr;

This little program sum up what my understanding:
C++:
//experiment pointers
#include <iostream>
using namespace std;

int main()
{
    int x = 10;
    int* ptrx;// initiate pointer ptrx
    ptrx = &x;// *ptrx = x = 10
    cout << " ptrx = " << ptrx << "     address of x = " << &x << "    x = " << x << "     *ptrx = " << *ptrx << "\n\n";
    int** pptrx;// initiate pointer to pointer pptrx
    pptrx = &ptrx;//pptrx pointing to ptrx
    cout << " address of pptrx = " << pptrx << "     *pptrx = " << *pptrx << "     **pptrx = " << **pptrx << "\n\n";
    return 0;
}
//    ptrx = 0135F97C     address of x = 0135F97C                    x = 10     *ptrx = 10

//    address of pptrx = 0135F970          *pptrx = 0135F97C                 **pptrx = 10

I copy the output in the cmd and put them in line 16 and line18 to summarize what I learn.

Thanks for all your patience.
 
  • #172
yungman said:
BUT all of a sudden after going through the response here slowly, it is like crystal clear to me!
1) That you can ONLY assign the SAME TYPE of values to the pointers, that is you can ONLY assign ADDRESS of variable/constant to a pointer eg. int *ptr; ptr = &var; where var can be int, double, const, char etc.
No, I don't think it is crystal clear to you. If it were crystal clear, you wouldn't be saying "where var can be int, double, const, char etc."

In your bolded example, var has to be type int. It can't be double, float, long, or any other type that isn't of type int. Also, const isn't a type -- it has to be a modifier of some type.
 
  • #173
Mark44 said:
No, I don't think it is crystal clear to you. You still don't seem to be getting it.
In your bolded example, var has to be type int. It can't be double, float, long, or any other type that isn't of type int. Also, const isn't a type -- it has to be a modifier of some type.
Address is always integers, it's never been a question, it's the type. It's never been clearer.

this is common sense with knowledge of hardware. That's the reason I feel it's so important to put hardware into perspective, not just treating as a high level language. You don't have a fraction of an address line in hardware.
 
  • #174
yungman said:
Address is always integers, it's never been a question, it's the type. It's never been clearer.
You've been told this several times. An address, currently, is an integer, but its type is not int! Until you come to terms with this, you aren't going to understand pointers.

Also, and I've said this before, addresses in the past were not integers.
yungman said:
this is common sense with knowledge of hardware. That's the reason I feel it's so important to put hardware into perspective, not just treating as a high level language.
Hardware and high-level language are two entirely different things.
 
  • #175
yungman said:
I am not confused

Yes, you are. If you weren't, you wouldn't have asked the questions you asked in post #165.
 

Similar threads

Replies
7
Views
2K
Replies
6
Views
2K
Replies
1
Views
1K
Replies
5
Views
2K
Replies
75
Views
5K
Replies
17
Views
2K
Replies
9
Views
2K
Back
Top