C++ 11中的简单向量初始化会返回奇怪的错误

pps*_*ith 4 c++ g++ vector c++11

编译这段代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

导致错误

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

稍微改变矢量初始化线(前面代码中的第5行)到(新代码中的第5,6行)

#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;
}
Run Code Online (Sandbox Code Playgroud)

使它成功编译.是什么赋予了?

g ++参数:-std = c ++ 11

Mik*_*our 7

因为vector,大括号初始化将向量内容初始化为初始化列表的内容,因此

std::vector<int> nos{N+2,0};
Run Code Online (Sandbox Code Playgroud)

将其初始化为2的大小,包含元素N+20.这使用了带有单个参数类型的构造函数std::initializer_list.

将大括号更改为括号会导致它使用双参数构造函数来指定所有元素的大小和初始值.这就是你想要的; 虽然你可以省略第二个参数,因为默认情况下元素是零初始化的.


Lig*_*ica 6

向量的列表初始化是一种提供初始元素列表的方法.它是一样的,提供构造函数的参数.

那是因为std::vector<T>有一个构造函数std::initializer_list<int>,当你使用时,它是最匹配的{x,y,..,z}:

[C++11: 8.5.4/2]:构造函数是初始化列表构造函数,如果它的第一个参数是类型std::initializer_list<E>或引用,可能std::initializer_list<E>是某些类型的cv-qualified E,并且没有其他参数,或者所有其他参数都有默认参数(8.3.6).[注意: 初始化列表构造函数优于列表初始化中的其他构造函数(13.3.1.7). -end note]模板std::initializer_list未预定义; 如果在<initializer_list>使用之前未包含标题std::initializer_list- 即使是未命名类型的隐式用法(7.1.6.4) - 程序也是格式错误的.

[C++11: 13.3.1.7/1]:当非聚合类类型的对象T被列表初始化(8.5.4)时,重载决策分两个阶段选择构造函数:

  • 最初,候选函数是类的初始化列表构造函数(8.5.4),T参数列表由初始化列表作为单个参数组成.
  • 如果找不到可行的初始化列表构造函数,则再次执行重载解析,其中候选函数是类的所有构造函数,T参数列表由初始化列表的元素组成.

所以:

std::vector<int> v{1,2,3,4,5,6,7};
Run Code Online (Sandbox Code Playgroud)

这个载体中有七个元素.

同样:

std::vector<int> nos{N+2, 0};
Run Code Online (Sandbox Code Playgroud)

该向量中有两个元素; 第一个有价值N+2,第二个有价值0.您的后续循环N,因为N在您的情况下是10,会导致内存损坏.

如果您改为编写以下内容:

std::vector<int> nos(N+2, 0);
Run Code Online (Sandbox Code Playgroud)

然后你使用期望的向量构造函数,其功能类似于std::vector::resize.