I'm studying this piece of code and what I don't understand is how p, q and r are related. We assign p to q and p to r, then display r, even though we do the increment on q.
Then this do ... while loop:
do {
cout<< "here" << *r << endl;
} while ( r != q);
How does it work? What are r and q equal to?
This is the full code:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
allocator<string> alloc;
auto const p = alloc.allocate(5);
auto q=p;
alloc.construct(q );
alloc.construct(q , 10, 'c');
alloc.construct(q , "hi");
auto r=p;
do{
cout<< *r << endl;
}while ( r != q);
std::cout<<"done"<<endl;
while (q != p){
alloc.destroy(--q);
}
q=p; r=p;
alloc.construct(q , 10, 'a');
alloc.construct(q , "hi again");
do{
cout<< "here" << *r << endl;
}while ( r != q);
alloc.deallocate(p, 5);
}
The output is:
output:
cccccccccc
hi
done
hereaaaaaaaaaa
herehi again
CodePudding user response:
p is a std::string * const, aka "constant pointer to mutable string". q and r are initialised to copies of p, meaning they are std::string *, aka "mutable pointer to mutable string".
p always points to the first element of the allocated array. q and r are modified to point to other elements of the array.
The first block
auto q=p;
alloc.construct(q );
alloc.construct(q , 10, 'c');
alloc.construct(q , "hi");
constructs 3 std::string objects, at consecutive positions in the array, starting with the first, incrementing q each time. q ends up pointing one-past the last std::string, to the forth element of the array.
The next block
auto r=p;
do{
cout<< *r << endl;
}while ( r != q);
displays these strings. After this, both q and r point to the forth element of the array.
The next block
while (q != p){
alloc.destroy(--q);
}
destroys each of those strings, in reverse order of construction. q ends up pointing to the first element, the same as p.
The first statement of the next block is a tautology, it sets q to the value it currently has, and then constructs 2 more strings. r is also reset to p.
q=p; r=p;
alloc.construct(q , 10, 'a');
alloc.construct(q , "hi again");
The next block displays those new strings, prepending "here".
do{
cout<< "here" << *r << endl;
}while ( r != q);
Finally the array is deallocated, without destroying the std::string objects. This might leak memory that the strings allocate, as their destructors are not run.
alloc.deallocate(p, 5);
