Basic vector of pointers question

Hey all,

My knowledge of pointers is admittedly quite poor, and I am sure I am missing something very basic, but after looking at it for several hours I still don't know what it is. So I just registered to see if someone can point me to the right direction.

It boils down to this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <vector>
using namespace std;

int main()
{
vector<int> the_vector;
vector<int*> the_pointer_vector;

for(int k=0; k<5; k++) 
  {
  the_vector.push_back(k);
  cout << "Initial addres for element " << k << " is " << &the_vector[k] << "\n";

  the_pointer_vector.push_back( &the_vector[k] );
  cout << "Pointer vector " << k << " is " << the_pointer_vector[k] 
    << " and points to " << *(the_pointer_vector[k]) << "\n";
  }
cout << "\n";
for(int k=0; k<5; k++) 
  cout << "Pointer vector " << k << " is " << the_pointer_vector[k] 
    << " and points to " << *(the_pointer_vector[k]) << "\n";
return 0;
}


Which outputs for instance this to the terminal:

Initial addres for element 0 is 0x18d7010
Pointer vector 0 is 0x18d7010 and points to 0
Initial addres for element 1 is 0x18d7054
Pointer vector 1 is 0x18d7054 and points to 1
Initial addres for element 2 is 0x18d7038
Pointer vector 2 is 0x18d7038 and points to 2
Initial addres for element 3 is 0x18d703c
Pointer vector 3 is 0x18d703c and points to 3
Initial addres for element 4 is 0x18d70b0
Pointer vector 4 is 0x18d70b0 and points to 4

Pointer vector 0 is 0x18d7010 and points to 26046528
Pointer vector 1 is 0x18d7054 and points to 0
Pointer vector 2 is 0x18d7038 and points to 2
Pointer vector 3 is 0x18d703c and points to 3
Pointer vector 4 is 0x18d70b0 and points to 4


My pointers seem to be pointing at the right addresses, but when I try to get the value they are pointing to a second time, the first elements of the vector are all garbled.

Thanks for your help!
Change the first for loop like this


1
2
3
4
5
6
7
8
9
for(int k=0; k<5; k++) 
  {
  the_vector.push_back(k);
  cout << "Initial addres for element " << k << " is " << &the_vector[k] << "\n";

  the_pointer_vector.push_back( new int(the_vector[k]) );
  cout << "Pointer vector " << k << " is " << the_pointer_vector[k] 
    << " and points to " << *(the_pointer_vector[k]) << "\n";
  }


but then, of course, deallocate dynamic memory

1
2
for( int k = 0; k < 5; ++k )
  delete the_pointer_vector[ k ];
Last edited on
My pointers seem to be pointing at the right addresses, but when I try to get the value they are pointing to a second time, the first elements of the vector are all garbled.


Have you checked the actual contents of the_vector during your second loop? Are the actual contents correct? My guess is that they are, and that the vector template is doing something odd with its memory management such that, by the time you hit the second loop, the_vector is storing the values at different memory locations from where they were when you stored the pointers in the first loop.

I'm not familiar enough with the way vectors work internally to say for sure whether this is what's happening.

TTT's suggestion changes what you're storing pointers to. Instead of storing pointers to the place where the_vector is storing the integers, it instead allocates new integers on the heap which have the same values as those in the_vector, and then puts pointers to that heap storage into the_pointer_vector.

Is there any particular reason you need to store both the values and the pointers in vectors? Or are you just experimenting out of curiosity?

Edit: reworded to make it clearer... I hope!
Last edited on
Addresses in first loop and second in the_vector_pointer are the same, but the_vector 's elements are stored in other memory locations, and so in second loop you have garbage instead of values


in first for loop when you write

for(int k=0; k<5; k++)
{
the_vector.push_back(k);
the_pointer_vector.push_back( &the_vector[k] );
}

in first step when k==0, *(the_pointer_vector[0] ) == 0 after assigning, but in second step when k ==1 , when you're doing

the_vector.push_back(k);
after that
*(the_pointer_vector[0]) != 0

this problem comes from segmentation

and if you want, instead of " new operator " here you can solve this problem by writing 2 seperate loops

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
int main()
{
vector<int> the_vector;
vector<int*> the_pointer_vector;

for(int k=0; k<5; k++) 
  {
  the_vector.push_back(k);
  cout << "Initial addres for element " << k << " is " << &the_vector[k] << "\n";
}

for( int k = 0; k < 5; ++k )
{
  the_pointer_vector.push_back( &(the_vector[k]) );
  cout << "Pointer vector " << k << " is " << the_pointer_vector[k] 
    << " and points to " << *(the_pointer_vector[k]) << "\n";
 }

cout << endl;

for(int k=0; k<5; k++) 
  cout << "Pointer vector " << k << " is " << the_pointer_vector[k] 
    << " and points to " << *(the_pointer_vector[k]) << "\n";

return 0;
}


but it is still dangerous, so it will be better to solve this problem with new operator
Last edited on
Ok got it. So it was a dynamic memory allocation problem right? The contents of the vector were growing because of the push_back() calls and their memory adress was shifting, therefore rendering my pointer vector unusable.

Ok thanks a lot guys!
And here one more solution is to reserve memory for vector before calling push_back

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int main()
{
vector<int> the_vector;
vector<int*> the_pointer_vector;

the_vector.reserve( 100 );
for(int k=0; k<5; k++) 
  {
  the_vector.push_back(k);
  cout << "Initial addres for element " << k << " is " << &the_vector[k] << "\n";

the_pointer_vector.push_back( &(the_vector[k]) );
  cout << "Pointer vector " << k << " is " << the_pointer_vector[k] 
    << " and points to " << *(the_pointer_vector[k]) << "\n";
 }

for(int k=0; k<5; k++) 
  cout << "Pointer vector " << k << " is " << the_pointer_vector[k] 
    << " and points to " << *(the_pointer_vector[k]) << "\n";

return 0;
}


first solution with using new is not actually right(logical wrong) because you want to have vector which saves addresses of another vector's elements, but in result addresses in first vector and in second vector are different
Last edited on
FWIW, I've just built and run the code, and get the similar results to Ender's for the dereferenced pointers in the second loop . I added a printout for the values in the_vector, and can confirm that they are still intact.

I added some more output for the new addresses of the members of the_vector_array, so that the second loop became:

1
2
3
4
5
6
7
8
    for(int k=0; k<5; k++)
    {
      cout << "Vector " << k << " is " << the_vector[k]
        << "and its address is " << &the_vector[k] << "\n";

      cout << "Pointer vector " << k << " is " << the_pointer_vector[k]
        << " and points to " << *(the_pointer_vector[k]) << "\n";
    }


and the entire output was:


Initial address for element 0 is 0x138d220
Pointer vector 0 is 0x138d220 and points to 0
Initial address for element 1 is 0x138d1c4
Pointer vector 1 is 0x138d1c4 and points to 1
Initial address for element 2 is 0x138d1e8
Pointer vector 2 is 0x138d1e8 and points to 2
Initial address for element 3 is 0x138d1ec
Pointer vector 3 is 0x138d1ec and points to 3
Initial address for element 4 is 0x138cdc0
Pointer vector 4 is 0x138cdc0 and points to 4

Vector 0 is 0and its address is 0x138cdb0
Pointer vector 0 is 0x138d220 and points to 20500912
Vector 1 is 1and its address is 0x138cdb4
Pointer vector 1 is 0x138d1c4 and points to 0
Vector 2 is 2and its address is 0x138cdb8
Pointer vector 2 is 0x138d1e8 and points to 2
Vector 3 is 3and its address is 0x138cdbc
Pointer vector 3 is 0x138d1ec and points to 3
Vector 4 is 4and its address is 0x138cdc0
Pointer vector 4 is 0x138cdc0 and points to 4


This indicates that, as new elements are added during the first loop, the vector is reallocating new storage for its array, and in the process, the array is being moved to a different address. By the time the 5th element has been added, the array has moved so that its first member is at 0x138cdb0, as we can see from the output of the second loop.

Edit: In fact, you can see the process of re-allocation happening. In the first loop, the address of the_vector[1] is lower than that reported for the_vector[0], indicating that when the second element (i.e. the value "1") is being added, the vector allocates a new array, which starts at a lower address than the one it initially allocated.

When the values 2 and 3 are added, the address increments by 4 bytes, so presumably it does not need to reallocate memory for those. But when the fifth element (value 4) is added, the address jumps again, indicating that it must have reallocated its storage again, at a new location.

So really, the addresses stored in the_pointer_vector are a mish-mash. Only the fifth one is pointing to the final location; all the rest are pointing to locations which are no longer being used.

Edit 2: Oops, looks like you worked it out yourself while I was typing!
Last edited on
Topic archived. No new replies allowed.