微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在函数内部声明一个指针,C++

如何解决在函数内部声明一个指针,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 举报,一经查实,本站将立刻删除。