代码vector<someType> myVector;
动态分配内存,因此存储的所有元素都将存在,直到调用删除为止。那么下面的vector<someType> *myVector = new vector<someType>();
如何与前一个不同(除了作为一个指针)?
这里有双重分配吗?
每个人都提到混合vector
和new
电话是邪恶的,但为什么呢?
如果它是邪恶的,为什么它是可接受的编译器代码,什么时候可以使用?
答案 0 :(得分:5)
你的第一个陈述不正确。 ParserError: Error tokenizing data. C error: Expected 5 fields in line 6, saw 7
中的元素将一直存在,直到矢量被销毁。如果vector<someType> myVector
是一个局部变量,它将在超出范围时自动销毁。您不需要明确调用删除。如果您考虑到由于可能引发的异常,您的vector<someType>
语句可能永远不会到达,导致内存泄漏,那么显式调用delete
是容易出错的。
例如。比较以下两种情况
delete
除了上述内容之外,向量动态分配内存以存储新元素也是如此。两种情况之间的区别是:
void foo()
{
std::vector<int> v;
v.push_back(1);
f(); // f is some operation that might throw exception.
} // v is automatically destroyed even if f throws.
void bar()
{
std::vector<int>* v = new std::vector<int>;
v->push_back(1);
f(); // f is some operation that might throw exception.
delete v; // You need to call delete explicitly here.
// The vector will be destroyed only if f doesn't throw.
}
v是堆栈中的一个对象,它动态分配内存以存储元素。
std::vector<int> v
v是指向动态分配对象的指针,它动态分配内存以存储元素。如前所述,你需要明确地调用delete来销毁这个对象。
答案 1 :(得分:3)
这里是否发生了双重分配?
取决于“双重分配”的含义。
您正在使用动态内存分配为std::vector
分配内存。 std::vector
的构造函数对std::vector
的元素执行相同的操作。如果你的意思是“双重分配”,那么答案就是“是”。
每个人都提到将矢量与新呼叫混合是邪恶的,但为什么呢?
使用
vector<someType> *myVector = new vector<someType>();
意味着您负责管理myVector
的动态分配内存。这引入了一些陷阱:
new vector<someType>()
可以抛出std::bad_alloc
。您必须添加代码来处理异常。如果不这样做,您将最终终止您的申请。
您必须确保释放内存。如果不这样做,程序会泄漏内存。
您必须确保在释放内存后不使用指针。
这些并不完全是 evil ,但您在应用程序代码中添加的工作量超出了必要的范围。
如果它是邪恶的,为什么编译器的代码可以接受?何时可以使用?
如果您有一个应用程序,您在某些核心组件中管理低级数据的原因是有意义的,那么使用动态分配的std::vector
是可以接受的。我认为将这些代码遍布整个代码库是不可接受的。显然,这是我的看法。 YMMV。
答案 2 :(得分:0)
代码
vector<someType> myVector;
动态分配内存,因此存储的所有元素都将存在,直到调用删除为止
没有。当此对象不再可用时,将删除此内存。
请考虑以下事项:
{
// Allocate a vector of 4 ints
vector<int> v(4);
// Do a lot of operations on this vector
}
此范围结束后,v
将被删除(RAII)。所以由它分配的内存会自动释放。
但是
{
// Allocate a vector of 4 ints
vector<int> *v = new vector<int>(4);
// Do a lot of operations on this vector
}
此范围结束后,v
对象不会被删除,直到您明确调用delete v
。
为了比指针更好的方法使对象逃避范围,使用shared_ptr
,unique_ptr
和weak_ptr
,这样可以避免忘记使用{{1 }}