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);