I wanted to learn about how to rotate a 1D array like a 2D array, but wound up finding this side-effect.
I had an STL array of 16 ints, and made a function to display the values in a 4×4 grid:
void func(std::array<int, 16> arr){
for(int i = 0; i < 16; ++i){
std::cout << arr[i] << ' ';
if((i + 1) % 4 == 0)
std::cout << std::endl;
}
}
but the first time I print an array (declared like this one specifically):
std::array<int, 16> arr{
1, 2, 3, 4,
0, 1, 2, 3,
0, 0, 1, 2,
0, 0, 0, 1
};
The output is:
16 2 3 4
0 1 2 3
0 0 1 2
0 0 0 1
I know the first element is the size because I changed the parameter and OG arr size to 17, then printed the array’s first element and the first element became 17, not the displayed value.
What’s even stranger is that if I copied the array to another of the same size I would get the expected result (1 2 3 4, newline and everything else.) (I made a copy because I was going to try rotate it.)
I defined the copy like this:
for(int i = 0; i <= 16;++i){
rotd_arr[i] = arr[i];
}
For the MRE requirers:
#include <iostream>
#include <array>
void func(std::array<int, 16> arr){
for(int i = 0; i < 16; ++i){
std::cout << arr[i] << ' ';
if((i + 1) % 4 == 0)
std::cout << std::endl;
}
}
int main (){
std::array<int, 16> arr{
1, 2, 3, 4,
0, 1, 2, 3,
0, 0, 1, 2,
0, 0, 0, 1
};
std::array<int, 16> rotd_arr;
for(int i = 0; i <= 16; ++i){
rotd_arr[i] = arr[i];//yes, I know I could have used the overloaded operator "="
}//yes, i also know there's an out-of-scope error
func(arr);
func(rotd_arr);
//the two ins
return 0;
}
UPDATE: minutes before posting this I found I had a scope error when I was copying the values from arr to rotd_arr. That fixed my problem, But now I have a different Question: Why was the first element the size of arr (or rotd_arr, I can’t really test that quickly), and why wasn’t it in rotd_arr instead of arr?
Noah M is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
24
Compare the two loops you wrote:
for(int i = 0; i < 16; ++i){
for(int i = 0; i <= 16; ++i){
The second one accesses both arrays out-of-bounds, and undefined behavior is invoked. This means anything could happen, including the erroneous output you observe.
I’d recommend using std::copy
to copy your array in this case.
std::copy(arr.begin(), arr.end(), rotd_arr.begin());
Or just:
rotd_arr = arr;
Invoking copy-assignment.
1