带返回 char* 函数的内存管理
Posted
技术标签:
【中文标题】带返回 char* 函数的内存管理【英文标题】:Memory Management with returning char* function 【发布时间】:2011-05-30 21:34:31 【问题描述】:今天,我不假思索地写了一个简单的函数返回一个 char* 基于给定枚举值的 switch 语句。然而,这让我想知道如何才能释放那段记忆。我所做的是这样的:
char* func()
char* retval = new char[20];
// Switch blah blah - will always return some value other than NULL since default:
return retval;
如果这是一个幼稚的问题,我深表歉意,但是释放内存的最佳方法是什么.我认为可行的解决方案是这样的
void func(char*& in)
// blah blah switch make it do something
int main()
char* val = new char[20];
func(val);
// Do whatever with func (normally func within a data structure with specific enum set so could run multiple times to change output)
delete [] val;
val = NULL;
return 0;
是否有人对此有更多见解和/或解释如何使用?
问候, 丹尼斯 M.
【问题讨论】:
您的第二个代码示例没有任何意义。您在 void 函数中返回,将字符值分配给指针,引用指针(有效但不经常有用)。 对不起,错字。应该没有回报。 顺便说一句,如果你返回一个char *
,我想你需要返回一个字符串而不是单个字符,在这种情况下你应该使用new char[size]
/delete []
。
是的,对于第二个示例中的拼写错误,我深表歉意。我在发这篇文章的时候写的很简短,没有仔细检查。
@Raged :还有问题。这不是错字。就是你不知道val = NULL;
之前delete val;
没有意义!
【参考方案1】:
在这种情况下,调用 func() 的人应该在不需要时释放内存。但是正确的删除是这样发生的:
delete val;
val = NULL;
【讨论】:
【参考方案2】:您是否考虑过使用 STL 类型或其他类而不是返回原始指针?例如,如果您的 char *
是一个字符串,请改用 std::string
并避免任何泄漏风险:
std::string func()
std::string retval("");
// Switch blah blah - will always return some value other than NULL since default:
return retval;
【讨论】:
【参考方案3】:你可以成对编写这样的函数,比如
Xyz* CreateXyz();
void DestroyXyz(Xyz *xyz);
Abc* NewAbc();
void DeleteAbc(Abc *abc);
或者您可以简单地将删除 Xyz/Abc 的责任转移给客户端,即调用该函数的人还必须在使用它后对返回的对象执行delete
。
无论您选择什么,请在文档中明确说明创建的对象应如何销毁。
我更喜欢配对函数,特别是如果在删除之前需要考虑很多事情!
顺便说一句,您应该更喜欢使用std::string
,而不是char*
。尽可能多地使用 STL。他们可以解决您的大部分问题!以上建议适用于 STL 不适合的情况!一般来说,更喜欢 STL!
【讨论】:
谢谢!我确实经常使用 STL,但是,我只是想知道在这种情况下如何进行这项工作。很棒的解决方案。 我要补充一点,创建一个类来保存资源(并在析构函数中释放它)通常会更好。所以创建 XYZ 和 ABC 类,而不是为它们创建新/删除函数。 @Winston Ewert:这也很好。但是如果一个人创建了使用和抛出类型的对象并且过于频繁,那么最好在您的设计中使用配对功能(如我的帖子中所述),以便用户可以在使用后立即销毁对象。 @Nawaz,我不确定你的意思是使用并抛出。我假设您的意思是您创建对象,在短时间内使用它,然后摆脱它。 (我建议 throw 不是一个好的术语选择,因为 throwing 用于异常。)但是,在这种情况下,我想在我的堆栈上创建一个对象,以便在函数结束时自动销毁它。我没有看到在那里使用配对函数会更好。 @Winston Ewert:如果他想从函数中返回对象,在这种情况下,配对函数是有意义的。这是另一种情况:***.com/questions/4555961/how-to-use-a-class-in-dll/…【参考方案4】:如果您打算从函数返回原始指针,您必须在文档中明确说明删除指针的责任,即谁拥有它。在这种情况下,您应该明确声明指针所有权转移给调用者,调用者负责delete
它。
虽然很多人都可以在文档中指定所有权,但通常最好在代码中强制执行此策略。特别是,智能指针经常用于此目的:当前的 C++ 标准提供了std::auto_ptr
,这是一个在副本上转移所有权的智能指针,即当你将它返回给调用者时,你正在转移目标std::auto_ptr
的所有权。请注意,std::auto_ptr
自动 delete
s 指向的内存在其销毁时仍然拥有它。即将推出的 C++ 标准提供了 std::unique_ptr
,其工作方式类似,但使用移动语义。
不幸的是,std::auto_ptr
不适用于数组(需要delete []
而不是delete
),因此您不能将其用于您的目的。我认为不包含数组的auto_ptr
的决定是故意的,因为如果您需要返回由它们自己的内存管理和复制处理的项目集合,STL 已经提供了您可能需要的所有容器。
特别是对于字符串,您应该简单地使用std::string
,而完全忘记这种内存管理和指针所有权问题。
【讨论】:
以上是关于带返回 char* 函数的内存管理的主要内容,如果未能解决你的问题,请参考以下文章