我的第一个问题是当函数结束时,函数中new分配的内存会被自动删除(释放)。
int* foo()
{
int *a = new int; //memory allocated for an int
*a = 3;
return (a);
}//function ends -- is memory for integer still allocated.
如果在函数结束后自动取消分配内存,那么我的下一个代码不应该给出一些与访问不属于我的内存有关的错误。
int main()
{
int *x = foo();
cout<<*x;
}
答案 0 :(得分:7)
不,它肯定没有。每个new
必须与delete
平衡。 (并且,为避免将来出现任何疑问,任何new[]
必须与delete[]
平衡。
C ++中的构造允许在容器对象超出范围时有效释放内存。请查看std::shared_ptr
和std::unique_ptr
。
答案 1 :(得分:2)
不,内存未被释放。
您应该使用delete a;
在Java或C#等语言中,有一个所谓的垃圾收集器,它在发现不再需要某些数据时处理内存释放。垃圾收集可以与C ++一起使用,但它不是标准的,在实践中很少使用。
但是,您可以使用其他机制来自动释放内存。共享指针就是其中之一。它们引入了额外的开销在常规C ++代码中,程序员通常负责手动管理内存(分配和解除分配)。对于初学者来说,在切换到更高级的机制之前学习基础知识非常重要。
答案 2 :(得分:0)
不,您有责任采购解除分配:
int *i = new int;
delete i;
然而,上述代码迟早会发展成几乎不可能使异常安全的东西。最好不要使用指针,或者如果你真的必须使用指针,请使用智能指针,它会在适当的时刻为你释放内存:
std::shared_ptr<int> i (new int);
*i = 0xbeef;
return i;
存在其他具有不同所有权语义的智能指针。
对于大多数现实世界的应用程序,智能指针引入的任何强加或假定的开销通常会对更昂贵的(我真正意味着省钱)的东西轻松起来,比如可维护性,可扩展性,异常安全性(其中所有内容都混入其他内容)二)。
永远不要忘记指针存在替代方案,具体取决于具体情况:
答案 3 :(得分:0)
这是一种不好的做法,可以在函数内动态分配,并依赖于其他函数的释放来解除分配。理想情况下,调用者应该分配空间,将其传递给调用函数,调用者在不使用时会释放。
void foo(int * a)
{
// a is pre-allocated by caller
*a = 3;
}//function ends -- caller takes care of allocation and deallocation
int main()
{
int *x = new int; // memory allocated for an int by caller
foo(x); // pass x as argument
cout << *x;
delete x; // deallocate, not required any more
return 0;
}
答案 4 :(得分:0)
如上所述,永远不会自动删除原始指针。这就是为什么我们不使用原始指针来控制生命周期。我们使用智能指针。
这是您在现代c ++中正确编写的代码段:
std::unique_ptr<int> foo()
{
return std::unique_ptr<int>(new int(3));
// or std::make_unique<int>(3) for c++14
// function will either std::move the unique_ptr or emplace it efficiently
}
int main()
{
// x will either be created in-place or move-constructed by foo()
std::unique_ptr<int> x = foo();
// potential bug! pointers can be null
if (x) {
std::cout << *x;
}
else {
std::cout << "x is null\n";
}
}