[英]std::vector memory allocation issue
I have a problem when trying to delete a vector of pointers: 我在尝试删除指针向量时遇到问题:
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;
I'm deleting each element from the whole vector, but I still get an assert. 我正在删除整个向量中的每个元素,但我仍然得到一个断言。 Can you please tell me what I'm doing wrong? 你能告诉我我做错了什么吗?
Thank you in advance. 先感谢您。
This doesn't do what you think it does: 这不符合你的想法:
v->assign(2, new float[2]);
One array of size 2 is allocated, then two pointers to it are stored in the vector
. 分配一个大小为2的数组,然后将两个指针存储在vector
。 When you delete
, the same pointer is deleted twice. delete
,会delete
相同的指针两次。
If you want a multidimensional array, you could try std::vector< std::array< float, 2 > >
. 如果你想要一个多维数组,你可以试试std::vector< std::array< float, 2 > >
。 Doing new
and delete
yourself are a code smell. 做new
并delete
自己是一种代码味道。 (The same goes for new vector …
; that is probably not what you really want.) (同样适用于new vector …
;这可能不是你真正想要的。)
THe v->assign(2, new float[2])
does the same as : v->assign(2, new float[2])
作用与:
float *f = new float[2];
for(int i = 0; i < 2; i++)
v->push_back(f);
of course, that's MOST likely not what you want - you probably want: 当然,这可能不是你想要的 - 你可能想要:
for(int i = 0; i < 2; i++)
{
float *f = new float[2];
v->push_back(f);
}
And using new
on vector
is just plain wrong - just use a plain vector. 在vector
上使用new
是完全错误的 - 只需使用普通向量。 Inside it, put a vector<float>
- or, if you just want two elements every time, use something like: 在它里面,放一个vector<float>
- 或者,如果你每次只想要两个元素,使用类似的东西:
struct f2 { float a; float b; };
vector<struct f2> v;
In general, having raw owning pointers is not a good idea (unless in special cases, like when you are defining some custom high-performance highly-specialized data structure). 通常,拥有原始 拥有指针并不是一个好主意(除非在特殊情况下,例如,当您定义一些自定义的高性能高度专业化数据结构时)。
In your code - unless you are in special cases - there should be no explicit calls to new
and delete
, in modern C++11/14. 在您的代码中 - 除非您处于特殊情况 - 在现代C ++ delete
,不应该显式调用new
和delete
。
Your code sample style seems more like Java and other garbage-collection-based reference-semantics-based languages style. 您的代码示例样式似乎更像Java和其他基于垃圾收集的基于引用语义的语言样式。 Instead, C++ tends to prefer value semantics (eg prefer: MyClass x;
to MyClass * px = new MyClass();
, and if you really need some owning pointer, use smart pointers like std::shared_ptr
or std::unique_ptr
): 相反,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<....>)
//
A more modern and correct way of writing your code can be using a vector
of vector
s (instead of a vector
of raw owning pointers float*
): 编写代码的更现代和正确的方法可以使用vector
的vector
S(而不是vector
原所属指针float*
):
//
// Vector of vectors (i.e. 2D matrix), allocated on the stack
// Note: no raw owning pointers here.
//
vector<vector<float>> v;
Then you can use use std::vector::push_back()
or some other std::vector
methods to populate the vector. 然后你可以使用std::vector::push_back()
或其他一些std::vector
方法来填充向量。
As a more high-performance and less-overhead alternative for a 2D matrix, you could use a single 1D std::vector
, and linearize the content of the 2D matrix in a single 1D contiguous vector, of size Rows * Columns
, eg: 作为2D矩阵的更高性能和更少开销的替代方案,您可以使用单个1D std::vector
,并在单个 1D 连续向量中线性化 2D矩阵的内容,其大小为Rows * Columns
,例如:
vector<float> matrix;
matrix.resize( Rows * Columns );
And to access element at position (rowIndex, columnIndex)
, you can use a formula like this (if you store matrix elements row-wise, ie row#1 , row#2 , ..., row#N ): 要访问位置处的元素(rowIndex, columnIndex)
,您可以使用这样的公式(如果您按行存储矩阵元素,即行#1 , 行#2 ,..., 行#N ):
indexInVector = columnIndex + rowIndex * Columns;
All this can be nicely wrapped in a class template template <typename T> class Matrix {...};
所有这些都可以很好地包装在类模板template <typename T> class Matrix {...};
, with proper methods to read and write matrix elements, and the containing std::vector<T>
as data member. ,使用适当的方法读取和写入矩阵元素,并包含std::vector<T>
作为数据成员。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.