使用函数初始化静态向量会导致内存泄漏吗?
Will initialization of static vector using a function give memory leak?
我得到了下面的代码。它编译得很好。
class A
{
public:
static std::vector<int> vInt;
static std::vector<int> Foo()
{
std::vector<int> tmp;
// EDIT: in the real application the values
// inserted in the vector depends on the result
// of other functions being called before Foo()
tmp.push_back(7);
tmp.push_back(9);
return tmp;
}
};
std::vector<int> A::vInt;
int main()
{
// .... some code
A::vInt = A::Foo();
// .... more code
}
但是我想知道它是否有内存泄漏?
我认为行:
std::vector<int> A::vInt;
正在构造一个向量(空向量)。
但该向量后来被以下行取代:
A::vInt = A::Foo();
所以第一个向量永远不会被破坏,我有内存泄漏。
是对还是错?
编辑:
我最初的问题没有提到在实际应用程序中我不能从一开始就调用 Foo() 。 Foo() 返回的值取决于需要首先调用的其他函数。抱歉不清楚...
没有泄漏,因为您正在使用 std::vector
。标准库会为您处理。
通常,除非使用 new
运算符,否则您不必担心泄漏。由于您没有进行动态分配(在堆上),因此不会泄漏任何内容;堆栈上的所有内容都将通过确定性破坏来处理。
你没有泄漏,但代码对我来说仍然看起来很复杂。我更喜欢这样的东西:
#include <vector>
class A
{
public:
static std::vector<int> vInt;
};
std::vector<int> A::vInt{ 7, 9 };
int main()
{
A a;
}
但一般来说,从函数返回局部向量是完全安全的。
理论上,编译器编译器将局部向量复制或移动到一个临时向量中,然后销毁局部向量。然后它将临时文件复制或移动到目的地并销毁临时文件。
标准明确允许绕过这一点——编译器可以(并且大多数会)将对目标的引用传递给函数。函数中的代码将通过该引用直接写入目标,因此根本不会进行复制或移动。
仍然:在这种情况下它毫无意义。只需在你定义它的地方初始化向量,你就完成了(除非你使用的是不支持这个的旧编译器,当然 - 但在那种情况下,最好尽可能更新编译器,而不是编写蹩脚的代码来适应旧的编译器。
您的代码不会有泄漏。 Foo() 返回的输出将在 A::vInt 的相同地址被覆盖。
检查下面的 Valgrind 输出,这也表明没有泄漏:
==25088== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 1)
==25088== malloc/free: in use at exit: 0 bytes in 0 blocks.
Write failed: Cannot allocate memoryrees, 20 bytes allocated.
Amits-MacBook-Pro:~ kamal$ ected errors, rerun with: -v
==25088== All heap blocks were freed -- no leaks are possible.
我得到了下面的代码。它编译得很好。
class A
{
public:
static std::vector<int> vInt;
static std::vector<int> Foo()
{
std::vector<int> tmp;
// EDIT: in the real application the values
// inserted in the vector depends on the result
// of other functions being called before Foo()
tmp.push_back(7);
tmp.push_back(9);
return tmp;
}
};
std::vector<int> A::vInt;
int main()
{
// .... some code
A::vInt = A::Foo();
// .... more code
}
但是我想知道它是否有内存泄漏?
我认为行:
std::vector<int> A::vInt;
正在构造一个向量(空向量)。
但该向量后来被以下行取代:
A::vInt = A::Foo();
所以第一个向量永远不会被破坏,我有内存泄漏。 是对还是错?
编辑: 我最初的问题没有提到在实际应用程序中我不能从一开始就调用 Foo() 。 Foo() 返回的值取决于需要首先调用的其他函数。抱歉不清楚...
没有泄漏,因为您正在使用 std::vector
。标准库会为您处理。
通常,除非使用 new
运算符,否则您不必担心泄漏。由于您没有进行动态分配(在堆上),因此不会泄漏任何内容;堆栈上的所有内容都将通过确定性破坏来处理。
你没有泄漏,但代码对我来说仍然看起来很复杂。我更喜欢这样的东西:
#include <vector>
class A
{
public:
static std::vector<int> vInt;
};
std::vector<int> A::vInt{ 7, 9 };
int main()
{
A a;
}
但一般来说,从函数返回局部向量是完全安全的。
理论上,编译器编译器将局部向量复制或移动到一个临时向量中,然后销毁局部向量。然后它将临时文件复制或移动到目的地并销毁临时文件。
标准明确允许绕过这一点——编译器可以(并且大多数会)将对目标的引用传递给函数。函数中的代码将通过该引用直接写入目标,因此根本不会进行复制或移动。
仍然:在这种情况下它毫无意义。只需在你定义它的地方初始化向量,你就完成了(除非你使用的是不支持这个的旧编译器,当然 - 但在那种情况下,最好尽可能更新编译器,而不是编写蹩脚的代码来适应旧的编译器。
您的代码不会有泄漏。 Foo() 返回的输出将在 A::vInt 的相同地址被覆盖。 检查下面的 Valgrind 输出,这也表明没有泄漏:
==25088== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 1)
==25088== malloc/free: in use at exit: 0 bytes in 0 blocks.
Write failed: Cannot allocate memoryrees, 20 bytes allocated.
Amits-MacBook-Pro:~ kamal$ ected errors, rerun with: -v
==25088== All heap blocks were freed -- no leaks are possible.