初始化正在影响与初始化无关的代码
Posted
技术标签:
【中文标题】初始化正在影响与初始化无关的代码【英文标题】:An initialization is affecting code that has no connection to the initialization 【发布时间】:2018-09-01 07:00:07 【问题描述】:在下面的代码中,我认为最后一个循环会打印四次1 2 3 4
,每换行一次。代码打印了四次 1 3 2 1
而不是 1 2 3 4
。
1, 3, 2, 1
的类型从double
更改为int
,问题就会消失。
如果我将double line[] = 1, 3, 2, 1
从 if-else 块中取出,问题就会消失。
我只是无法理解变量double line[]
的初始化如何影响vector <double *> v
的赋值。
#include <iostream>
#include <cmath>
#include <vector>
int main()
std::vector <double*> v;
for(int i = 0; i < 4; i++)
double line[] = 1, 2, 3, 4;
v.push_back(new double[4]);
v[std::abs(v.size()) - 1] = line;
if(0 > 1)
else
double line[] = 1, 3, 2, 1;
for(int i = 0; i < 4; i++)
for(int j = 0; j < 4; j++)
std::cout << v[i][j] << ' ';
std::cout << '\n';
【问题讨论】:
Your code doesn't even compile 在输入帖子时出错。对不起。我已经对其进行了编辑以反映正确的代码。 Still doesn't compiledouble line[] = 1, 3, 2, 1;
在该范围内声明了一个新变量,该变量不以任何方式连接到具有相同名称的另一个变量,然后该范围结束,该变量也是如此。您的第一个循环所做的只是造成内存泄漏。
你的第一个 line
在每次迭代后都会被销毁,因此 v[x]
是一个悬空指针,会产生未定义的行为
【参考方案1】:
这里
for(int i = 0; i < 4; i++)
double line[] = 1, 2, 3, 4;
v.push_back(new double[4]);
v[std::abs(v.size()) - 1] = line;
您所拥有的只是内存泄漏 + 未定义的行为。
您正在堆栈中创建line
,作为每个迭代器的结尾,它超出了范围,这意味着您没有按照您的意图进行操作。访问后,它们会为您提供 UB。
其次,您每次都在堆中创建new double[4]
,而您没有管理/释放后者,导致内存泄漏!
你可能想这样做:
#include <vector>
#include <array>
std::vector <std::array<int, 4>> v;
for (int i = 0; i < 4; i++) v.emplace_back(std::array<int, 4> 1, 2, 3, 4 );
将给出一个 4x4 维度的数组向量(二维)。 并使用基于范围的循环访问它们:
for (const std::array<int, 4>& row : v)
for (const int element : row) std::cout << element << " ";
std::cout << std::endl;
但是,您似乎正在执行任务,您必须以std::vector <int*> v;
方式处理。如果是这样,则需要进行额外的取消分配以释放您使用 new
关键字创建的内存。
std::vector <int*> v;
for (int i = 0; i < 4; i++)
v.emplace_back(new int[4] 1, 2, 3, 4 ); // create and store to vector
for (const int* row : v)
for (int j = 0; j < 4; j++)
// do print
for (int i = 0; i < 4; i++) delete[] v[i]; // free the memory using delete
但是,我建议使用 smart pointers,因为您倾向于 C++ 而不是 C。
比如上面的代码可以写成std::unique_ptr
std::vector <std::unique_ptr<int[]>> v;
for (int i = 0; i < 4; i++)
v.emplace_back(std::unique_ptr<int[]>(new int[4] 1, 2, 3, 4 ));
for (const std::unique_ptr<int[]>& row : v)
for (int j = 0; j < 4; j++)
std::cout << row[j] << " ";
// no mannual memory management is required.
【讨论】:
std::vector<std::array<double,4>>
是更好的选择。
@PaulMcKenzie 你是对的,因为大小是固定的。让我更新一下。
另外,通过使用std::array
,OP 的代码几乎不需要更改。所需要做的就是从代码中完全删除 line[]
并直接使用大括号初始化器。以上是关于初始化正在影响与初始化无关的代码的主要内容,如果未能解决你的问题,请参考以下文章