Do functions that return pointers require that I delete the value that is returned?
假设我有一个执行某项任务的函数。 该函数返回一个指向int的指针。 我的问题是这样的:我是否必须释放内存或这种通用格式好吗?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| int *do_something()
{
int *local{ new int };
//do_something_here
return local;
delete local;
}
int main()
{
int *result{ new int };
result = do_something();
delete result;
return 0;
} |
-
您需要为代码中的每个new调用delete。请注意,return语句后的delete local;将不起任何作用。
-
首先,它取决于你如何获得指针。第二,return之后什么都不重要,因为它永远不会到达。如果它是指向用new分配的东西的指针,那么你最终必须delete它??。
-
这是一个模板。我不会分享可能成为专有代码的东西。
-
@ Sirknow-a-ton尽管如此,没有人愿意复制你的代码(特别是如果它包含返回new ed指针的函数),我们只想要一个代表性的例子。请参见最小可重复的示例。
-
你不应该首先返回一个新的int。这样做就像在代码中放置陷阱一样,迟早会后悔
-
为什么要发出这个:int *result{ new int };,它分配内存,然后为结果赋值?
-
@ Sirknow-a-ton注意,由于指针被分配到原始值delete d之前,result指向的对象将被泄露。
-
等待如何返回指针并释放内存?
-
@ Sirknow-a-ton你不能两者兼顾,至少不能从函数的上下文中完成。请使用类似std::unique_ptr的智能指针。
-
请修复你的例子,我认为如果函数返回int或int*,它会增加一些混乱,它不是100%清除
-
你无法正确地从int返回返回一个指向int的指针,你需要int* do_something()才能使它成为合法的。 π?ντα?ε?说,每new一个delete。获取new内存所有权的线程/对象应该是执行delete ing的那个。程序员可以明确地向任何查看其所拥有内存分配的代码的人明确说明。
-
@ Sirknow-a-ton这在概念上是不可能的。然后指针将指向已删除的对象并且无用。当你完成它时,你只有delete。如果你从一个函数返回它通常意味着你没有完成它,或者你不需要首先返回它。
-
那么你的int函数返回一个int而不是一个int指针。此外,您不能通过删除跟随返回。一旦达到回报,该功能就会超出范围。如果需要,您可以稍后使用返回的指针释放分配的内存。
-
值得庆幸的是,现代c++不鼓励使用new。
-
@drescherjm根据我的理解,我应该使用它?我不应该说,"为这种类型的变量腾出空间",这样我以后可以用它做些什么吗?
-
应该使用@ Sirknow-a-ton make_unique(连同智能指针)。
-
我想说的是在c++11(2011标准)及更高版本中有更好的方法可以消除在大多数情况下使用new的需要。更好的方法不易出错,更容易使用。
-
@drescherjm他们现在在用什么版本的c ++?
-
c++17 c++20在标准化过程中。每3年都有一个新的/更新的标准。
-
en.wikipedia.org/wiki/C%2B%2B20
-
函数不要求删除(非验证者?),但也许你的团队的编码标准可以。 C ++语言没有"要求"阻止您在一个函数中新建一个对象实例并在另一个函数中删除该实例。如果你应该这样做,编译器不会检测到并且不会"警告"或"错误"。这样做并不是未定义的行为。此外,没有"要求"每个新的都有相应的删除。
-
此外,cppreference.com基本上具有从C ++ 98到C ++ 20的整个C ++标准,以(大多数)可读格式提供示例。
-
你教吗? 你的意思是我可以在某个函数A中声明空格并删除另一个函数B中的空格而不将新的对象传递给B? 显然没有"要求",但如果你想防止内存泄漏,那么你需要以某种方式释放占用的空间。
-
@ Sirknow-a-ton"你的意思是我可以在某个函数A中声明空格并删除另一个函数B中的空格而不将新的对象传递给B?" 你一定是误会了。 当然,您需要跟踪通过使用new正确调用delete实现的指针。
要记录对象所有权的传输并防止内存泄漏,您应该使用unique_ptr返回在堆上分配的对象。这是C ++的最佳实践。
有关更多详细信息,请参阅C ++核心指南:永远不要通过原始指针(T *)或引用(T&)转移所有权:
Reason
If there is any doubt whether the caller or the callee owns an object, leaks or premature destruction will occur.
-
或者shared_ptr。
-
@Tzalumen根据我的经验,在99%的情况下,shared_ptr用于避免考虑所有权,导致次优设计和循环引用。所以,如果可能的话,我建议坚持使用unique_ptr。
-
@Tzalumen我认为大多数时候不需要从创建者类型的函数返回shared_ptr。
My question is this: do I have to deallocate memory or is this general format okay?
是的,如果动态分配内存,则必须释放内存。否则,您冒着程序内存使用的风险,无法控制地增长并消耗所有可用内存 - 或者至少消耗超过必要的内存。
Do functions that return pointers require that I delete the value that is returned?
仅仅因为函数返回一个指针,并不一定意味着它必须被删除。一个例子:
1 2 3 4 5 6 7 8 9
| int* a_function(int* ptr) {
return ptr + 1;
}
int main() {
int arr[2];
int* iptr = a_function(arr);
// must not delete iptr
} |
函数可以要求调用者删除返回的指针。您的do_something示例函数似乎就是这样的函数。这是一个非常糟糕的功能设计。如果分配的所有权转移给调用者,则应使用智能指针。
1 2
| return local;
delete local; |
返回后发表声明毫无意义。它们永远不会被执行。
1 2
| int *result{ new int };
result = do_something(); |
在这里,你丢失了new-expression返回的值。因此,不再可能delete该值 - 后来的delete会删除新值。这种指针值的丢失以及随后无法释放内存被称为内存泄漏。
-
所以假设我有一些带有内存泄漏的程序P.尽管有泄漏,它仍会编译。那么内存泄漏是什么呢?地址是否已满,因此我们在路上的内存较少?我假设允许内存地址不被清空导致以后没有内存可用,我是否正确?我不是在读一本我刚才自学的书。
-
@ Sirknow-a-ton内存泄漏的后果是你无法释放内存。如果你反复这样做(通常,程序倾向于不止一次调用函数),那么每个分配使用越来越多的内存。计算机没有无限的内存,最终会耗尽。
-
等等,这是否意味着如果运行内存泄漏的代码,那么我的笔记本电脑将具有未解除分配的地址?或者我的操作系统处理了吗?
-
@ Sirknow-a-ton只要有可用内存,您的操作系统将为您的程序提供更多内存。一旦内存耗尽,您的操作系统将终止程序直到内存可用。除非你不走运,否则操作系统可能会选择你的漏洞程序来终止。
-
@ Sirknow-a-ton实际操作系统在该过程结束时回收它为进程提供的所有内存。因此,在有问题的程序运行时泄漏只是一个问题。