5

I'm writing a method that creates a copy of an array of arrays of floats. I was getting some extremely weird values after debugging this, so I thought I'd ask about this since I wasn't able to figure this out by reading about C++ array FAQs.

Here's the relevant parts of the code (it's part of an enormous program, with most of the stuff irrelevant for this post):

// height and width are integer global variables
void method () {
    float testArray[height][width];
    for(int j = 0; j < height; ++j) {
        for(int i = 0; i < width; ++i) {
            testArray[j][i] -= 0.0;
            std::cout << testArray[j][i] << std::endl;
        }
    }
}

(In my tests, height = 32 and width = 256, but that shouldn't be relevant.) When I initialize testArray, it's values should all be 0.0, correct? Then, in the loop, I subtract 0.0 from a certain element in testArray, which should logically not change the value at all. But printing the values of testArray as a debugging step result in some weird values, such as the following snippet:

[...]
0
[...]
-3.23805e-24
[...]
8.40779e-45
[...]
1.79513e+37
[...]
0
[...]
3.19586e+36
[...]

The most worrisome values are the infinite ones, such as the fourth number listed above. I honestly don't know why this is occurring. Shouldn't all these values still be approximately 0.0? I thought it had to do with imprecision of floating point arithmetic, but that shouldn't result in an infinite value ....

TakeS
  • 596
  • 1
  • 6
  • 14
  • 7
    When you initialise the array, the values are not initialised to 0, you are just being allocated a random section of memory with the right size. – Sinkingpoint Nov 19 '12 at 20:51
  • 2
    You should make sure you are compiling at the highest warning level, most compilers should warn you that your array is uninitialized. – Jesse Good Nov 19 '12 at 20:53
  • Wow, that was a quick fix, thanks. My compiler did not warn me at all. I have no idea why I thought this would initialize values to 0 ... – TakeS Nov 19 '12 at 20:55
  • Languages like Java initialise values to 0. C based ones don't. – Sinkingpoint Nov 19 '12 at 21:03

4 Answers4

7

No, when you declare your array like that it will be uninitialized since it's a builtin type. You'll need to initialize it to zero yourself before doing the subtraction.

But note that declaring an array as you have (with presumably non-const dimensions) is a compiler extension and not part of the language.

I would just use vector which solves both problems at once.

std::vector<std::vector<float> > testArray(height, std::vector<float>(width));
Mark B
  • 91,641
  • 10
  • 102
  • 179
  • Thanks for the answer. There's an easy way for me to change height and width to be constants, so I think I'll stick with an array of arrays here. – TakeS Nov 19 '12 at 21:00
3

Try initializing the values in the array:

float testArray[height][width] = {};
David Rodríguez - dribeas
  • 192,922
  • 20
  • 275
  • 473
2

This line creates an uninitialized array, element values can be any garbage:

float testArray[height][width];

To initialize it with float default values (zero) use following syntax:

float testArray[height][width] = {};
Rost
  • 8,379
  • 24
  • 45
2

THIS ANSWER IS WRONG, BUT I AM LEAVING IT SO NOONE TRIES IT!

Use this very explicit definition:

float testArray[height][width] = {{0.0f}};

to ensure that every value in your array is initialized to zero. Otherwise, the values in the array will be undefined. I feel that this is the most "readable" solution.

WHY IS IT WRONG?

As @Dave mentions below, although this solution works for this case, it is misleading. It explicitly assignes only the first element of testArray to 0.0, while it value-initializes all the other elements in the array.

The correct solution is indeed:

float testArray[height][width] = {};

which value-initializes all the elements in the array (to the default value 0.0f for type float.

dinkelk
  • 2,766
  • 2
  • 24
  • 42
  • 1
    This would not compile, it shall be `{ { 0.0 } }` – Rost Nov 19 '12 at 21:00
  • 3
    -1 This is deceptive, albeit an unbelievably common mistake. What you wrote explicitly assigns 1 element to `0.0` (should be `0.0f` or `.0f` by the way) and value-initializes the rest of the elements (which in the case of float, initializes them to `0.0f`). The best way to do this is to write `= {};` with *no* value; or to explicitly write a value for each element (not always practical). – David Nov 19 '12 at 21:17
  • @Dave Can you help me understand? I was reading through http://stackoverflow.com/questions/1613341/what-do-the-following-phrases-mean-in-c-zero-default-and-value-initializat, but it is hard to follow. What is the difference between the assignment of the first element, and the "value-initialization" of the rest of the elements? – dinkelk Nov 19 '12 at 21:26
  • 2
    [This is value initialization.](http://en.cppreference.com/w/cpp/language/value_initialization) It means different things in different situations. Basically, in your snippet, if you changed `0.0` to `1.0` the first element would be 1 and the rest would be 0. – David Nov 19 '12 at 21:27
  • @Dave Ah! I understand now. Thank you. I will leave this answer up so hopefully others can learn from my mistake. – dinkelk Nov 19 '12 at 21:29