I thought I liked the idea of std::array from C++11, but it looks like it has some quarks. I found this out because the following code gives a segmentation fault:
#include<array>
#include<iostream>
int main() {
std::array<std::array<int*, 5>, 4> sum;
//Initialize sum array
std::cout << sum.size() << " " << sum[0].size() << "\n";
for (size_t i = 0; i < sum.size(); i++) {
for (size_t j = 0; j < sum[0].size(); j++) {
if (i == 0 || j == 0)
*(sum[i][j]) = 0;
else
sum[i][j] = nullptr;
}
}
return 0;
}
This outputs:
4 5
Segmentation fault (core dumped)
sum.size()
returns 4, as expected, and sum[0].size()
returns 5
, as expected; IE it seems like we have an array with 4 rows and 5 columns. However, I get a segmentation fault when I try to execute this program (as shown above). This link suggests that reversing the order of the way I access my array (as in change sum[i][j]
to sum[j][i]
) should work, but I also get a seg-fault then too. This made me think I might have been doing something wrong with my pointers (I'm a little rusty with my C++), so I changed sum to be an array of integers, so it read as follows:
#include<array>
#include<iostream>
int main() {
std::array<std::array<int, 5>, 4> sum;
//Initialize sum array
std::cout << sum.size() << " " << sum[0].size() << "\n";
for (size_t i = 0; i < sum.size(); i++) {
for (size_t j = 0; j < sum[0].size(); j++) {
if (i == 0 || j == 0)
sum[i][j] = 0; //works as sum[j][i] too!!!
else
sum[i][j] = 1;
std::cout << sum[i][j];
}
std::cout << "\n";
}
std::cout << "here\n";
return 0;
}
Which works, and outputs:
4 5
00000
01111
01111
01111
here
However, I'm confused, because if I switch the sum[i][j]
's to sum[j][i]
's, it also works and outputs the same thing! I would expect to get a seg-fault when I try sum[5][0]
during the final iteration of the inner loop the first time that it is run! I am now willing to call myself hella confused. What is going on?
Extra info: I am using g++ 4.8.4 with the -std=c++11 flag set.
The first snippet doesn't work because you are accessing random memory locations. You declared (essentially) a bidimensional array of (uninitialized) pointers, and in your code you are dereferencing them, which is undefined behavior and very likely to cause a segfault (you are trying to write on random memory locations, which are most likely non mapped in the current virtual address space).
The second snippet is fine; reversing the two indexes is wrong, but you don't get any error because no explicit bound checking is performed by std::array
(or by the compiler on the underlying C arrays). What happens when you get to the invalid index (4 on the first index) is technically still undefined behavior; in practice, you are probably overwriting unrelated variables on the stack, and the program keeps on going by chance.