使用填充构造函数实例化的向量的 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));
我正在尝试创建一个所需大小的向量,然后将向量的内存重新用于循环的多次迭代。我使用“填充”向量构造函数将向量设置为所需的初始容量。
当我提到“填充”构造函数时,我指的是 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));