C++ 疑惑

2020-02-09 13:57:50 +08:00
 hua123s

经常看到如下代码。非 C++程序员但需要使用该语言。

char *cstr = new char[arg0.length() + 1];
delete [] cstr;

是否当接收返回值是指针的都需要 delete ?并且方法内局部变量也需要 delete ?

如果不操作可能导致的问题是什么么?

2963 次点击
所在节点    C++
18 条回复
classyk
2020-02-09 14:03:30 +08:00
1. 不是,要看情况而定。
2. 不释放的话,越跑可用内存越少,最后分配不到内存,就挂了

c/cpp 是需要手工维护内存使用的。智能指针能起一部分作用
optional
2020-02-09 14:07:36 +08:00
智能指针走起来
jmc891205
2020-02-09 14:08:16 +08:00
你手动去堆上申请的内存 你要负责释放
不然就导致内存泄漏
stephenyin
2020-02-09 14:23:41 +08:00
1.简单的说, 用 new 得到的指针都需要 delete.
2.不释放的话,该进程使用的内存就越来越多,如果对应的指针变量丢失就是内存泄露了.
hua123s
2020-02-09 14:30:08 +08:00
@optional 新手 不太懂 233
hua123s
2020-02-09 14:31:23 +08:00
@stephenyin

int a = 1;
int* b = &a;
这个时候 b 就不用 delete ?(●'◡'●)
ipwx
2020-02-09 14:34:45 +08:00
@hua123s 指针不关键。new 出来的要 delete, malloc 出来要 free。就这么简单
hua123s
2020-02-09 14:36:42 +08:00
@ipwx 好的 么么哒
stephenyin
2020-02-09 14:43:31 +08:00
@hua123s #6 不需要
shilyx
2020-02-09 16:36:06 +08:00
1、new 出来的就要 delete

2、每个需要 delete 的只能 delete 一次

ps:c++危急,后继无人。有问题到我群里来问 1046884003,义务解答(不代做作业)
wzzzx
2020-02-09 16:57:59 +08:00
用了 new 就一定要用 delete,记得就好
neroransom
2020-02-09 22:03:51 +08:00
局部变量生命周期结束就自动消亡了。
指针就是一个四字节的变量。
delete 与否和指针没关系,delete 是用 new 进行动态内存分配后,释放 new 出来的内存用的,因为他不像局部变量一样会自动消亡。

以你的代码为例,如果不 delete []cstr,则 cstr 这个指针函数运行完了就没了,但是他指向的那片空间还在,而且没有能找到他的指针了,这种程序多跑几次内存就爆了。
levelworm
2020-02-22 03:57:56 +08:00
凡是 new 的都是创建在 heap 上的,所以不释放就一直在那里。new 和 delete 必须成对,哪一个多了都有问题。
FrankHB
2020-02-22 10:13:08 +08:00
八成得把写这代码的拉过来扁一顿。
合格的 C++ 程序员最起码不应该“经常”整出来这种代码让你看到。

@neroransom LP64/ILP64/LLP64: ?
@levelworm free store: ??
[[fallthrough]];
@stephenyin @ipwx @shilyx placement new: ???
levelworm
2020-02-22 11:34:50 +08:00
@FrankHB 写习惯了,delete...
hua123s
2020-02-22 13:17:12 +08:00
@FrankHB ...你说的完全看不懂。
FrankHB
2020-02-22 13:42:27 +08:00
@hua123s 首先清楚大多数 C++ 用户不应该直接使用 new 和 delete 就够了。
具体原因么……替代的东西多了去了,没必要用;正常都是直接创建对象或者带所有权的智能指针( std::unique_ptr 和 std::shared_ptr )+不带所有权的引用 /视图( std::reference_wrapper/observer_ptr/string_view/span/...)。
两者的区别是,前者是非常底层的东西,必须自觉才能保证 no resource leak,并且还得小心才能保证 basic exception safety ;后者只要实现对(不滥用前者)默认就不会有这个问题。这种基本的 invariant guarantee 是在任何程序设计中都应当是普遍的重要的默认应该保持的东西,只不过不少语言根本不提供像 new 和 delete 这种依赖自觉不手贱才能维护 invariant 的危险操作,才让你看不出来这种保证的重要性。
要是几十年前古董代码用户水平又不够只会 new/delete 还能理解,现在正常情况一般代码根本不应该直接用这种底层而危险的东西。就算 new/delete 用对了不会导致功能问题,出现 new 而不能保证排除漏 delete 这种会导致最终用户直接受到影响(资源泄漏)的 invariant breakage,放任这种代码导致每个出现 new 的地方都要人肉找一遍 delete (因为这方面工具不保证完全靠谱)才能最终确保正确,这直接就是可维护性灾难。所以正常的 code review 就不应该放过这种低级问题,应用代码看到 new 和 delete 就直接回炉重造基本不会有错。
需要打死的还有一个理由是因为历史原因这方面实践普遍比较差,所以替代虽然理由应该明确,风格上也很混乱。很多大的项目可能自己有一套 API 做专门的封装。相比之下 Rust 就没 C++ 那么糟烂(但是也并不容易上手)。

另外不是给你看的,不过也算是基础内容(虽然大多数 C++ 用户这方面基础完全不合格,麻烦知耻):
1. new 不一定从 heap 上分配。new 底层实现的 operator new 作为 allocation function 且没被用户自定义时,分配的是 free store,而 heap 是 free store 在 hosted implementations 的一种普遍实现。这不是必要的。
2. 标准库提供默认的 placement new 就不分配。与此相对应该注意不遗漏是析构函数调用语法(……以及 std::launder 什么乱七八糟的),而不是 delete ; placement delete 仅在异常时被调用。
neroransom
2020-02-23 18:58:58 +08:00
@FrankHB 好吧,说得不够严谨

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/643199

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX