Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple vector initialization in C++11 returns weird error

Compiling this piece of code:

#include <vector>

long long sumOfMedians(int seed, int mul, int add, int N, int K)
{
  std::vector<int> nos{N+2,0};
  for(int i=0; i<N; i++)
    {
      if(i == 0)
    nos[i] = seed;
      else
    nos[i] = (nos[i-1]*mul + add)%65536;
    }
}

int main()
{
  sumOfMedians(3,1,1,10,3);
  return 0;
}

causes an error

*** Error in `./a.out': free(): invalid next size (fast): 0x00000000006e8010 ***
[2]    31743 abort (core dumped)  ./a.out

While slightly changing the vector initialization line (line 5 in previous code) to (line 5,6 in new code)

#include <vector>

long long sumOfMedians(int seed, int mul, int add, int N, int K)
{
  std::vector<int> nos;
  nos.resize(N+2,0);
  for(int i=0; i<N; i++)
    {
      if(i == 0)
    nos[i] = seed;
      else
    nos[i] = (nos[i-1]*mul + add)%65536;
    }
}

int main()
{
  sumOfMedians(3,1,1,10,3);
  return 0;
}

Causes it to compile successfully. What gives?

g++ parameter: -std=c++11

like image 899
ppsreejith Avatar asked Dec 07 '22 00:12

ppsreejith


1 Answers

For vector, brace-initialisation initialises the vector contents to the contents of the initialiser list, so

std::vector<int> nos{N+2,0};

initialises it to a size of 2, with elements N+2 and 0. This uses the constructor that takes a single parameter of type std::initializer_list.

Changing the braces to parentheses causes it to instead use the two-argument constructor that specifies the size and initial value for all elements. That's what you want here; although you could leave out the second argument since elements are zero-initialised by default.

like image 151
Mike Seymour Avatar answered Dec 26 '22 04:12

Mike Seymour