0

The below code works fine on ideone, gives an output of

10000
10000

as expected

However on my local machine, the output is of the sort

9990
9998

All the code does is create a vector of 10k int's and count the number of 0's in it. Once using a class, and once in main.

If I run the code locally in debug mode, it results in

0
0

I'm using codeBlocks on Windows 7 with the default GNU GCC Compiler (though it compiles C++, so I guess its different than the Linux GCC which does only C)

#include<iostream>
#include<vector>
using namespace std;
class vecttest
{
    vector<int> vect;
    public:
    vecttest()
    {
        vect.reserve(10000);
    }
    int zcount()
    {
        int count=0;
        for(int i=0;i<10000;i++)
        {
            if(vect[i]==0)
                count++;
        }
        return count;
    }
};
int main()
{
    vecttest v;
    cout<<v.zcount();

    vector<int> v2;
    v2.reserve(10000);
    int count=0;
        for(int i=0;i<10000;i++)
        {
            if(v2[i]==0)
                count++;
        }
    cout<<endl<<count;
}

ideone link: http://ideone.com/q1XRvQ

Emil Laine
  • 41,598
  • 9
  • 101
  • 157
Akash
  • 1,716
  • 2
  • 23
  • 43
  • Why do you think it should default to zero? You are just reserving space – Ed Heal Apr 04 '15 at 06:42
  • @EdHeal thats the behaviour mentioned in the accepted answer at http://stackoverflow.com/questions/5222404/c-value-of-uninitialized-vectorint – Akash Apr 04 '15 at 06:44
  • 4
    You should use `vect.resize(10000,0);` – πάντα ῥεῖ Apr 04 '15 at 06:45
  • @πάνταῥεῖ Thanks, that did it.. now I see that reserve doesnt initialize, resize does – Akash Apr 04 '15 at 06:47
  • @Akash - reserve is just changing capacity. Resize changes the amount allocated – Ed Heal Apr 04 '15 at 06:48
  • Akash, check out https://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html and add `-D_GLIBCXX_DEBUG` to the compiler commandline. This would possibly have told you that you are doing something wrong before asking here. – Ulrich Eckhardt Apr 04 '15 at 07:46

1 Answers1

2

The method reserve(..) only guarantees that the space is allocated. It does not guarantee the values in the elements of the vector. The only thing that will happen is that your counting will not crash. The resulting value is implementation/allocation/etc dependent.

The core idea that is necessary to understand about containers and iterators is that they are the same insecure as simple arrays:

char b1[100];
vector<char> b2(100);

void f()
{
   char c1 = b1[200];
   char c2 = b2[300];
}

In both cases compiler will generate code that will pick up something outside of the array. Both examples trigger undefined behavior. Maybe the code will crash, maybe not. Both accesses are equally bad.

The main reason for such design is speed. Access to array should be fast. This is core idea of C/C++. The value of the index is the responsibility of the programmer. Compiler will not check. Like it or not, this is so.

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51
  • The counting isn't even guaranteed to not crash. Reading from outside the actual size of the vector is undefined behaviour. (As is interpreting an un-constructed memory region as an `int`, by some interpretations of the strict aliasing rules). – Mankarse Apr 04 '15 at 08:06
  • Very strictly speaking you are right. I can bet any amount that there is no non debug implementation what will crash. Debug implementation will throw exception... – Kirill Kobelev Apr 04 '15 at 08:09
  • Debug implementations will very surely not throw exceptions, as exceptions are for normal error handling. With undefined behaviour, you want to abort execution so that the programmer can fix the code, but it's not something that your process could recover from. – Ulrich Eckhardt Apr 04 '15 at 08:18