使用填充构造函数实例化的向量的 C++ 无错误

C++ free error with vector instantiated with fill constructor

我正在尝试创建一个所需大小的向量,然后将向量的内存重新用于循环的多次迭代。我使用“填充”向量构造函数将向量设置为所需的初始容量。

当我提到“填充”构造函数时,我指的是 cplusplus.com 所指的“填充”构造函数(参见 here):

(2) fill constructor
Constructs a container with n elements. Each element is a copy of val (if provided).

但是,当我尝试执行此操作时,出现以下错误(有关详细信息,请参阅下面的示例):

free(): invalid next size (fast)

为了简化问题,我创建了以下最小可重现示例:

#include <vector>
#include <iostream>

int main()
{
    const int k = 1;

    std::vector<int> values{(2*k+1) * (2*k+1)};
    int num_items = 0;

    for (int i = 0; i < 2*k+1; ++i) {
        for (int j = 0; j < 2*k+1; ++j) {
            std::cout << "Before assignment: " << num_items << std::endl;
            values[num_items] = 0;
            num_items++;
            std::cout << "After assignment: " << num_items << std::endl;
        }
    }
    
    std::cout << "At end, num_items is " << num_items << std::endl;
}

当我运行这个的时候,这是完整的输出:

Before assignment: 0                                                                                                                                                                 
After assignment: 1                                                                                                                                                                  
Before assignment: 1                                                                                                                                                                 
After assignment: 2                                                                                                                                                                  
Before assignment: 2                                                                                                                                                                 
After assignment: 3                                                                                                                                                                  
Before assignment: 3                                                                                                                                                                 
After assignment: 4                                                                                                                                                                  
Before assignment: 4                                                                                                                                                                 
After assignment: 5                                                                                                                                                                  
Before assignment: 5                                                                                                                                                                 
After assignment: 6                                                                                                                                                                  
Before assignment: 6                                                                                                                                                                 
After assignment: 7                                                                                                                                                                  
Before assignment: 7                                                                                                                                                                 
After assignment: 8                                                                                                                                                                  
Before assignment: 8                                                                                                                                                                 
After assignment: 9                                                                                                                                                                  
At end, num_items is 9                                                                                                                                                               
*** Error in `./a.out': free(): invalid next size (fast): 0x0000000001f00c20 ***                                                                                                     
Aborted (core dumped)

由于程序在最后一个打印语句成功执行后有无效释放,我的假设是释放向量时发生无效释放。我不明白为什么会这样。我还从我的 print 语句中知道我从未分配给矢量大小范围之外的索引。

我知道这个示例的样子,我本可以使用 push_back() 而不是使用填充构造函数设置向量的大小。然而,这只是一个最小的可重现示例 - 在我的真实代码中,我创建了一次向量,然后重新使用内存(每次都覆盖向量中的值)。

如果仍然不清楚为什么我不能只使用 push_back(),请在评论中告诉我,我可以更新我的答案以提高清晰度。

您声称的“完整输出”并不是您显示的程序的完整输出,因为它包含 values.size() 的输出,应该是 1。这也是导致您遇到的问题的原因:您有一个单个元素的向量,并越界访问它,这会导致 未定义的行为.

如果您使用大括号初始化 std::vector,它将使用 std::initializer_list constructor of std::vector.

如果要用 (2*k+1) * (2*k+1) 个元素初始化向量,则需要使用括号代替:

std::vector<int> values((2*k+1) * (2*k+1));