尝试删除指针向量时遇到问题:
std::vector<float*> *v;
v = new std::vector<float*>;
v->assign(2, new float[2]);
for (int i = 0; i < 2; ++i)
{
delete[] v->at(i);
}
delete v;
我正在删除整个向量中的每个元素,但我仍然得到一个断言。你能告诉我我做错了吗?
提前谢谢。
答案 0 :(得分:5)
这不符合你的想法:
v->assign(2, new float[2]);
分配一个大小为2的数组,然后将两个指针存储在vector
中。当您delete
时,相同的指针会被删除两次。
如果你想要一个多维数组,你可以尝试std::vector< std::array< float, 2 > >
。自己做new
和delete
是一种代码味道。 (同样适用于new vector …
;这可能不是你真正想要的。)
答案 1 :(得分:1)
v->assign(2, new float[2])
的作用与:
float *f = new float[2];
for(int i = 0; i < 2; i++)
v->push_back(f);
当然,这可能不是你想要的 - 你可能想要:
for(int i = 0; i < 2; i++)
{
float *f = new float[2];
v->push_back(f);
}
在new
上使用vector
是完全错误的 - 只需使用普通向量即可。在其中,放一个vector<float>
- 或者,如果你每次只想要两个元素,请使用类似的东西:
struct f2 { float a; float b; };
vector<struct f2> v;
答案 2 :(得分:1)
一般情况下,拥有原始 拥有指针并不是一个好主意(除非在特殊情况下,就像在定义一些自定义的高性能高度专业化数据结构时一样) )。
在您的代码中 - 除非您遇到特殊情况 - 在现代C ++ 11/14中,不应该对new
和delete
进行明确调用。
您的代码示例样式似乎更像Java和其他基于垃圾收集的基于引用语义的语言样式。相反,C ++倾向于选择值语义(例如,更喜欢:MyClass x;
到MyClass * px = new MyClass();
,如果你真的需要一些拥有指针,请使用智能指针,如std::shared_ptr
或std::unique_ptr
):
// Your original code:
//
// std::vector<float*> *v;
// v = new std::vector<float*>;
//
// Not good, since:
//
// 1. You have a std::vector of owning pointers
// (std::vector<float *>)
//
// 2. You have a raw owning pointer for the containing std::vector itself
// (v = new std::vector<....>)
//
更现代,更正确的代码编写方式可以使用vector
vector
s(而不是vector
原始拥有指针float*
):< / p>
//
// Vector of vectors (i.e. 2D matrix), allocated on the stack
// Note: no raw owning pointers here.
//
vector<vector<float>> v;
然后,您可以使用std::vector::push_back()
或其他一些std::vector
方法来填充矢量。
作为2D矩阵的更高性能和更少开销的替代方案,您可以在std::vector和线性化 2D矩阵的内容>单个 1D 连续向量,大小为Rows * Columns
,例如:
vector<float> matrix;
matrix.resize( Rows * Columns );
要访问位置(rowIndex, columnIndex)
的元素,您可以使用这样的公式(如果您按行存储矩阵元素,即行#1 ,行#2 ,..., row#N ):
indexInVector = columnIndex + rowIndex * Columns;
所有这些都可以很好地包装在类模板template <typename T> class Matrix {...};
中,使用适当的方法来读取和写入矩阵元素,并将std::vector<T>
包含为数据成员。