簡體   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