Dereference list::end() - c++11

I was playing around with std::list. Similarly to other containers, std::list::end refers to the past-the-end element of a std::list (ref).
So, we would expect the below code to print 1, 2, 3, 4, 5 (which it does):
std::list<int> l { 1, 2, 3, 4, 5 };
for (auto it = l.begin(); it != l.end(); ++it)
{
std::cout << *it << ", ";
}
std::cout << std::endl;
However, the second line of the second code snippet should not print 5, but it does:
std::cout << *l.begin() << std::endl;
std::cout << *l.end() << std::endl;
Output: 1 and 5.
Why? I'm using GCC 11 and C++11 (same for C++20 btw).

You can see the reason if you build in debug mode, with the -D_GLIBCXX_DEBUG command line flag:
/usr/include/c++/8/debug/safe_iterator.h:270:
Error: attempt to dereference a past-the-end iterator.
Objects involved in the operation:
iterator "this" # 0x0x7fff50ac8670 {
type = __gnu_debug::_Safe_iterator<std::__cxx1998::_List_iterator<int>, std::__debug::list<int, std::allocator<int> > > (mutable iterator);
state = past-the-end;
references sequence with type 'std::__debug::list<int, std::allocator<int> >' # 0x0x7fff50ac85d0
}
Aborted
As with other containers, dereferencing the end() iterator is undefined. It only happens to work by accident in non-debug mode.

Related

Why I cannot use a decltype in range-for with multi-dimension arrays?

I have a problem here. I am trying to use decltype in range-for loop for using multi-dimension array:
int a[][4]{
{0, 1, 2, 3 },
{4, 5, 6, 7 },
{8, 9, 10, 11}
};
for (auto& row : a) { // reference is needed here to prevent array decay to pointer
cout << "{";
for (auto col : row)
cout << col << ", ";
cout << "}" << endl;
}
decltype (*a) row{ *a};
cout << sizeof(row) << endl;
cout << typeid(row).name() << endl;
// for (decltype(*a) row : *a) {
// for (int col : row)
// cout << col << ", ";
// cout << endl;
// }
With auto I can easily iterate over the the array But with decltype it doesn't work for me.
What I get above if I uncomment the code is: cannot convert from int to int(&)[4].
That is because the line for(decltype(*a) row : *a) is incorrect. Try to read it correctly: for each array of 4 int from a, not from *a.
The code may look like:
for (decltype(*a) row : a) {
for (int col : row)
cout << col << ", ";
cout << endl;
}
Dereferencing a (*a) with decltype will yield an array of 4 integers. So the type is int[4]. Unlike using keyword auto where it yields int*.

Eigen reduction examples are not building with Error C2100 illegal indirection

I am trying to use examples from
Reduction Dimensions
section of Eigen Tensors README
This:
// Create a tensor of 2 dimensions
Eigen::Tensor<int, 2> a(2, 3);
a.setValues({{1, 2, 3}, {6, 5, 4}});
// Reduce it along the second dimension (1)...
Eigen::array<int, 1> dims({1 /* dimension to reduce */});
// ...using the "maximum" operator.
// The result is a tensor with one dimension. The size of
// that dimension is the same as the first (non-reduced) dimension of a.
Eigen::Tensor<int, 1> b = a.maximum(dims);
cout << "a" << endl << a << endl << endl;
cout << "b" << endl << b << endl << endl;
And other examples from that section gives me Error C2100 illegal indirection compile error. In VS 2015. Everything else works and compile well. Any ideas what is the problem with that code?
Eigen::array<int, 1> dims({1 /* dimension to reduce */});
Should be changed to:
const std::array<DenseIndex, 1> action_cards_dims = { 1 };

Iterating over a vector with std::adjacent_find and custom predicate

I am having trouble searching for and printing out pairs of elements in a vector that are separated by 2 from left to right. I need to collect the pairs
The example data that I am operating on is:
std::vector<int> myvector = { 1, 3, 3, 5, 7, 9, 13, 10, 12 };
Given that the std::adjacent_find predicate is:
static const auto gAdjacentPred = [](
const int& lhs, const int& rhs) {
std::cout
<< "(" << lhs << ":" << rhs << ")?"
<< std::string((rhs == lhs+2)? "true" : "false")
<< std::endl;
return (rhs == lhs+2);
};
I was expecting to get the following result (with multiple calls to the predicate along the way):
{1,3}, {3,5}, {5,7}, {7,9} & {10,12}
Ideally thought (and I have no idea how to do this) I would like to merge the values that satisfy the predicate in the middle of the input data ... 3, 5, 7, 9 ... as a single result {3, 9}.
The problem is that I do not really understand how to properly loop over the collection. I did see that std::next(iter) is a trick that I can use to peek ahead at the right most value satisfying the lambda, however this can sometimes point to the end of the collection.
I was expecting that the way I was looping over the data would show multiple calls to the predicate as it iterated over the collection - as it turns out it only calls the predicate function one time (when I assign to the adjIter. Also, in the results I see that the pair 13 & 10 seems to satisfy the predicate. Could someone explain what is going on here as I need to find pairs from left to right that differ by some value - in my case here 2 (with the left side less than the right (I am searching for increasing values from left to right).
(1:3)?true
{1,3}
{3,5}
{7,9}
{13,10}
The problem is that the last pair is also considered
static const auto gAdjacentPred = [](
const int& lhs, const int& rhs) {
std::cout
<< "(" << lhs << ":" << rhs << ")?"
<< std::string((rhs == lhs+2)? "true" : "false")
<< std::endl;
return (rhs == lhs+2);
};
std::vector<int> myvector = { 1, 3, 3, 5, 7, 9, 13, 10, 12 };
auto adjIter = std::adjacent_find (
myvector.begin(), myvector.end(),
gAdjacentPred);
while (adjIter != myvector.cend()) {
auto second = std::next(adjIter);
// print both sides
if (second != myvector.cend()) {
std::cout << "{" << *adjIter << "," << *second << "}" << std::endl;
adjIter +=2;
} else {
adjIter++;
}
}

Address of an instance emplaced to std::vector is invalid

I have 2 std::vectors:
to first vector, I emplace instance
to second vector, I want to store the address of the instance just emplaced
But it does not work, i.e., the stored address differs from the emplaced instance's address.
If it matters at all, I'm on Linux and using g++ 5.1 and clang 3.6 with -std=c++11.
Here's a working example to illustrate the problem.
#include <iostream>
#include <vector>
struct Foo {
Foo(int a1, int a2) : f1(a1), f2(a2) {}
int f1;
int f2;
};
int main(int, char**) {
std::vector<Foo> vec1;
std::vector<Foo*> vec2;
int num = 10;
for (int i = 0; i < num; ++i) {
vec1.emplace_back(i, i * i);
// I want to store the address of *emplaced* instance...
vec2.push_back(&vec1.back());
}
// same
std::cout << "size 1: " << vec1.size() << std::endl;
std::cout << "size 2: " << vec2.size() << std::endl;
// same for me
std::cout << "back 1: " << &vec1.back() << std::endl;
std::cout << "back 2: " << vec2.back() << std::endl;
// typically differ ?
std::cout << "front 1: " << &vec1.front() << std::endl;
std::cout << "front 2: " << vec2.front() << std::endl;
for (int i = 0; i < num; ++i) {
std::cout << i + 1 << "th" << std::endl;
// same for last several (size % 4) for me
std::cout << "1: " << &vec1[i] << std::endl;
std::cout << "2: " << vec2[i] << std::endl;
}
}
Questions
Is it correct behavior ? I guess it's caused by storing the address of temporary instance but I want to know whether it's permitted by the standard (just curious).
If above is true, how to work around this ? I resolved this by changing first one to vector<unique_ptr<Foo>> but is there any idiomatic way ?
Two options:
1) You can simply fix your test. You just need in you test preallocate enough memory first with
vec1.reserve(10);
Well, this is implementation details for std::vector. As more and more items are added to std::vector it needs to get more space for them. And this space must be contigious. So when there is not enough space for a new element std::vector allocates a bigger block of memory, copies existing elements to it, add the new element and finally frees the block of memory that it used before. As a result addresses that you stored in vec2 might become invalid.
However, if you preallocate enough memory for 10 elements then you code is correct.
Or, since reserving memory is sort of tricky thing to do
2) use std::deque since insertion and deletion at either end of a deque never invalidates pointers or references to the rest of the elements (http://en.cppreference.com/w/cpp/container/deque) and forget about the problem with invalidated addresses. So no need to reserve memory.

how does the below code output 3? (how does the below code read?)

The specific part I do not understand is how the -a in the if statement changes -3 to 3. Can someone explain how the -a changes a = -3 to a = 3?
#include <iostream>
int main(){
signed a = -3;
if (a < 0){ std::cout << -a << std::endl; }
else { std::cout << a << std::endl; }
system("pause");
return 0;
}
It's an example of unary negative, when a=-3 (which is less than 0, the code then enters the if block) then -a is -(-3) which is 3.
This code won't change the value of 'a' at all. It will remain 3 (a=3) even after execution of if statement. You can check this by adding
std::cout << a << std::endl;
in your if statement. The system just prints the value of -1*a i.e. (-a)

Resources