从动态分配的解引用指针默认初始化非常量引用函数参数是否会造成内存泄漏?
Does default-initializing a non-const reference function parameter from a dynamically allocated dereferenced pointer create a memory leak?
我在这之前,将不得不处理 C++98,可能是 C++03 和 C++11:
type1 myfunc( type2& var = /*some value of type "type2"*/ )
{
// Some code
}
我试过了:
type1 myfunc( type2& var = *(new type2) )
{
// Some code
}
当然可以,但我不确定这是否会造成内存泄漏。这段代码在计算机内存中的确切作用是什么?
如果我做不到,除了重载我的功能,我还有其他解决方案吗?
此代码将在使用默认参数的情况下造成内存泄漏,除非 myfunc
释放它(这将是一个 hack):
type1 myfunc( type2& var = *(new type2) ) {
// Some code
delete &var; // Very bad, don't do it like that.
}
当使用为 var
指定的参数进行调用时,没有 delete
就不会发生内存泄漏。这是因为编译器看到您正在为引用参数传递参数,而不是分配 new type2
.
创建默认引用而不造成内存泄漏的一种方法是定义一个静态一次性变量,并将其用作引用:
static type2 throwaway;
type1 myfunc( type2& var = throwaway ) {
// Some code
}
这样,不需要查看对 var
所做修改的调用者就可以调用您的函数,而无需为其指定引用。当然,如果 myfunc
对 var
进行了任何修改,调用者将无法看到它们。
问题被标记为C++11,所以我想你可以使用std::unique_ptr
来解决这个问题。
一个小例子
#include <memory>
#include <iostream>
std::size_t myfunc( std::string const & var
= * std::unique_ptr<std::string>(new std::string("default string")) )
{ return var.size(); }
int main ()
{
std::cout << "default: " << myfunc() << std::endl;
std::cout << "argument: " << myfunc("no default") << std::endl;
return 0;
}
希望这对您有所帮助。
---添加了C++98/C++03解决方案---
不清楚 OP 想要使用什么语言。
对于 C++98/C++03,可以使用 std::auto_ptr
而不是 C++11 std::unique_ptr
.
我记得 std::auto_ptr
已从 C++11 中弃用,因此如果您不能使用 C++11(或更新的标准),请仅 使用它)
下面的例子应该是 C++98 兼容的(我也删除了 const
)
#include <memory>
#include <iostream>
std::size_t myfunc(std::string & var
= * std::auto_ptr<std::string>(new std::string("default string")) )
{ return var.size(); }
int main ()
{
std::string noDef("no default");
std::cout << "default: " << myfunc() << std::endl;
std::cout << "argument: " << myfunc(noDef) << std::endl;
return 0;
}
如果您分配了内存但不删除它,那么您就会发生内存泄漏,无论您通过解引用、引用或指针操作进行了哪些恶作剧。
我在这之前,将不得不处理 C++98,可能是 C++03 和 C++11:
type1 myfunc( type2& var = /*some value of type "type2"*/ )
{
// Some code
}
我试过了:
type1 myfunc( type2& var = *(new type2) )
{
// Some code
}
当然可以,但我不确定这是否会造成内存泄漏。这段代码在计算机内存中的确切作用是什么? 如果我做不到,除了重载我的功能,我还有其他解决方案吗?
此代码将在使用默认参数的情况下造成内存泄漏,除非 myfunc
释放它(这将是一个 hack):
type1 myfunc( type2& var = *(new type2) ) {
// Some code
delete &var; // Very bad, don't do it like that.
}
当使用为 var
指定的参数进行调用时,没有 delete
就不会发生内存泄漏。这是因为编译器看到您正在为引用参数传递参数,而不是分配 new type2
.
创建默认引用而不造成内存泄漏的一种方法是定义一个静态一次性变量,并将其用作引用:
static type2 throwaway;
type1 myfunc( type2& var = throwaway ) {
// Some code
}
这样,不需要查看对 var
所做修改的调用者就可以调用您的函数,而无需为其指定引用。当然,如果 myfunc
对 var
进行了任何修改,调用者将无法看到它们。
问题被标记为C++11,所以我想你可以使用std::unique_ptr
来解决这个问题。
一个小例子
#include <memory>
#include <iostream>
std::size_t myfunc( std::string const & var
= * std::unique_ptr<std::string>(new std::string("default string")) )
{ return var.size(); }
int main ()
{
std::cout << "default: " << myfunc() << std::endl;
std::cout << "argument: " << myfunc("no default") << std::endl;
return 0;
}
希望这对您有所帮助。
---添加了C++98/C++03解决方案---
不清楚 OP 想要使用什么语言。
对于 C++98/C++03,可以使用 std::auto_ptr
而不是 C++11 std::unique_ptr
.
我记得 std::auto_ptr
已从 C++11 中弃用,因此如果您不能使用 C++11(或更新的标准),请仅 使用它)
下面的例子应该是 C++98 兼容的(我也删除了 const
)
#include <memory>
#include <iostream>
std::size_t myfunc(std::string & var
= * std::auto_ptr<std::string>(new std::string("default string")) )
{ return var.size(); }
int main ()
{
std::string noDef("no default");
std::cout << "default: " << myfunc() << std::endl;
std::cout << "argument: " << myfunc(noDef) << std::endl;
return 0;
}
如果您分配了内存但不删除它,那么您就会发生内存泄漏,无论您通过解引用、引用或指针操作进行了哪些恶作剧。