繁体   English   中英

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

[英]Simple vector initialization in C++11 returns weird error

编译这段代码:

#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;
}

导致错误

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

稍微改变矢量初始化线(前面代码中的第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;
}

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

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

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

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

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

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

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

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

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

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

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

所以:

std::vector<int> v{1,2,3,4,5,6,7};

这个载体中有七个元素。

同样:

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

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

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

std::vector<int> nos(N+2, 0);

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

你正在用大括号初始化初始化一个size-2向量 (vector有一个接受std::initializer_list<int>的构造std::initializer_list<int>

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

然后要求索引2( 超出范围 ):

nos[2] = (nos[2 - 1] * mul + add) % 65536;

你可能想写:

  std::vector<int> nos(N+2,0);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM