如何解决在函数内部声明一个指针,C++
当我在函数内注册一个新指针时会发生什么? 我承认,应该销毁指针的名称。 但是分配的内存会发生什么?会不会是内存泄漏? 在我的示例中,数据对象在函数终止后是否保持有效,或者它只是偶然工作,在更复杂的实例中容易出现未定义的行为? 在这个例子中应该在哪里放置删除是正确的? 还是应该避免这种写法?
int * one (void);
int main (void){
int *two = new int;
*two = *one ();
cout << "Address: " << one() << "|" << *one() << endl; // Address: 0xe51a78|5555
cout << "Address: " << two << "|" << *two << endl; // Address: 0xe519d8|5555
}
int * one (void){
int * pFun = new int; // declaration of a pointer inside a function
*pFun = 5555;
return pFun;
}
解决方法
你写的代码会泄露。
==365== Memcheck,a memory error detector
==365== Copyright (C) 2002-2017,and GNU GPL'd,by Julian Seward et al.
==365== Using Valgrind-3.17.0.GIT and LibVEX; rerun with -h for copyright info
==365== Command: ./test
==365==
==365==
==365== HEAP SUMMARY:
==365== in use at exit: 8 bytes in 2 blocks
==365== total heap usage: 3 allocs,1 frees,72,712 bytes allocated
==365==
==365== 4 bytes in 1 blocks are definitely lost in loss record 1 of 2
==365== at 0x484D103: operator new(unsigned long) (vg_replace_malloc.c:342)
==365== by 0x10919E: main (in /petsc/test)
==365==
==365== 4 bytes in 1 blocks are definitely lost in loss record 2 of 2
==365== at 0x484D103: operator new(unsigned long) (vg_replace_malloc.c:342)
==365== by 0x1091CC: one() (in /petsc/test)
==365== by 0x1091A7: main (in /petsc/test)
==365==
==365== LEAK SUMMARY:
==365== definitely lost: 8 bytes in 2 blocks
==365== indirectly lost: 0 bytes in 0 blocks
==365== possibly lost: 0 bytes in 0 blocks
==365== still reachable: 0 bytes in 0 blocks
==365== suppressed: 0 bytes in 0 blocks
==365==
==365== For lists of detected and suppressed errors,rerun with: -s
==365== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
注意上面我删除了两个打印调用,因为第一个调用 one()
两次,导致 2 个额外的泄漏
您永远不会直接存储 one()
返回的指针,而是立即取消引用它。这具有丢弃该地址的效果。更好的方法是执行以下操作:
// two is an uninitialized pointer
int *two;
// Assign the returned pointer to two
two = one();
// Assign the value pointed to by two (and in effect one()) to three and use it
int three = *two;
functionThatExpectsAnInt(three);
// Alternatively use two directly,it points to valid memory whose value has not changed
functionThatExpectsAnInt(*two);
// Clean up resources from one()
delete two;
对于返回分配内存的函数,调用者是函数返回的资源的有效“所有者”。所以调用者必须要么释放资源,要么将它们传递给另一个会这样做的函数。
,动态分配的对象一直存在,直到它被取消分配或“释放”。这正是动态分配的目的:创建生命周期不依赖于作用域的对象(也就是说,不会在下一个右花括号处结束,就像自动变量一样)但也不是无限的,就像全局或静态的一样。相反,动态分配对象的生命周期完全在运行时“动态”决定。
返回指向动态分配对象的指针是一种常见模式,例如 factory functions。
Jacob 是对的,您的程序没有释放分配的对象。在程序结束之前的某个时刻释放所有资源(这包括打开的文件和套接字以及系统资源的其他句柄)是一种很好的方式。但这会有什么不同吗?不,因为 all operating systems clean up the memory after program termination (同时链接的答案使得清理反正 :-) )。您的程序可以根据需要运行多少次,而不会耗尽内存。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。