《#诗盗#·非正常人类》:一觉好梦游仙,管它屋冷床寒!参编善恶演幻,听尽庸人说谗。
注解
写于软件非正常人类研究中心。改编自霹雳角色“人觉·非常君”和“禅剑一如寄昙说”的诗号。
一觉游仙好梦,任它竹冷松寒。
轩辕事,古今谈,风流河山。
沉醉负白首,舒怀成大观。
醒,亦在人间;梦,亦在人间。
看红尘冉冉,须臾无间,参遍昙华演换。
问法珠玄玄,方寸有变,听尽默剑说禅。
《#诗盗#·非正常人类》:一觉好梦游仙,管它屋冷床寒!参编善恶演幻,听尽庸人说谗。
写于软件非正常人类研究中心。改编自霹雳角色“人觉·非常君”和“禅剑一如寄昙说”的诗号。
一觉游仙好梦,任它竹冷松寒。
轩辕事,古今谈,风流河山。
沉醉负白首,舒怀成大观。
醒,亦在人间;梦,亦在人间。
看红尘冉冉,须臾无间,参遍昙华演换。
问法珠玄玄,方寸有变,听尽默剑说禅。
UMU 认为有一个目的是:需求细分(另外还有优化的目的)。考虑以下代码:
1 | class Movable |
因为 Movable& m 没有用 const 修饰,所以可以在内部改变 m 的状态。如果加上 const 则不行:
1 | Movable(const Movable& m) : i(m.i) |
那么没加 const 的集合,减去有 const 的集合,等于什么?答案就是:移动构造函数
1 | Movable(Movable&& m) : i(m.i) |
分成 const Movable& 和 Movable&& 两个,更严格、更清晰,这是好事。而 std::move 做的事情是为了正确调用移动构造函数(Movable&&),而不是被隐式转为 const 而错误地调用了复制构造函数(const Movable&),不要在意什么左值、右值的,太烧脑了……
扩展阅读:《从4行代码看右值引用》,https://www.cnblogs.com/qicosmos/p/4283455.html
本文宣告 UMU 正式开始学习 C++。之前只系统学过 C,自然地了解了一些 C++ 的皮毛(可以认为是 C+),然后就一直用着 C+ 开发,最近看了一些现代 C++ 代码,感觉是时候好好学习 C++ 了……后续会把学习中记的笔记发出来,尽量简短明了。
delete
和 delete[]
的本质区别?
他们都需要两步:先析构元素,再释放内存。
不同编译器、不同的优化开关和优化场景都可能导致不同结果。实际实现反汇编确认,以汇编为准。下面介绍一种可能的实现。
当 ptr 指向的是基础类型数组时,在析构这一步时,delete ptr
和 delete[] ptr
等价。
当 ptr 指向类对象数组时,两者的差别在于调用多少个析构函数,delete
只调用第一个元素的析构函数,delete[]
则调用所有元素的析构函数。
1 |
|
当数组只有 1 个元素时,实际上两者的析构次数也一样。那么,delete[]
怎么知道当初分配了多少个元素呢?下一节有答案。
对于基础类型,多数编译器(验证过 MSVC、clang++)会把 new[]
实现为不加任何“头部”,因为基础类型不需要析构。
对于类对象数组,delete[] ptr
会先对 ptr 做减法,因为实际上 new[]
分配的是一个结构体:
1 | template <typename T> |
但返回值指向 data。data 之前的字段可以称之为“头部”,这部分内容的实现具有不确定性。大约可以用下列代码解释:
1 | // new T[element_count]; |
所以 delete[] ptr
需要先对 ptr 做个位移,才能得到当初由 operator new
分配的内存。
举例:
1 | struct EmptyClass { |
auto ptr = new EmptyClass[1]
需要分配一个 size_t 和一个 EmptyClass,在 x64 下是 8+1 字节,但 ptr 指向的是这块内存的第 8 字节。delete[] ptr
对 ptr 减掉 8 个字节得到 new 分配的一块 8+1 字节的内存的地址,对其进行释放。注:NewData 结构体里的 element_count,使得 delete[]
知道应该析构 element_count 个元素。
以下讨论不是基础类型的情况:
new
出来的东西拿去 delete[]
会怎么样?会野指针或访问越界或内存泄漏,因为读取 element_count 的位置是未定义行为:可能直接拒绝访问
也可能读出一个巨大的数值,然后做巨多次析构,而析构第 0 个元素时还好,从第 1 个开始又是访问越界型未定义行为!
还可能读出 0,导致没有析构。
恰巧读出 1,正确析构,但释放内存时,由于会对指针减 sizeof(size_t) 字节,最终释放错误。
new[]
出来的东西拿去 delete
会怎么样?会内存泄漏。数组有不止一个元素时,析构就无法保证全部完成;即使只有唯一的一个元素,在析构完后的释放内存也有问题,释放的并不是当初分配出来的地址,需要减 sizeof(size_t) 字节。注:如果底层的内存管理器有一定容错机制,比如会对齐,那么可能真的走狗屎运了,减没减 sizeof(size_t) 字节最终都可以正确完成,那只能说……C++ 真牛!
《#诗盗#·#量子邪说#之观世寂莲宇督工》:问道不知何处寻,行路沧茫但由心。情深慧极总成幻,千秋唯奉观世音。
Arya Avalokiteshvara:量子邪说之观世寂莲宇督工,简称观世音。
改编自霹雳角色“邃无端”的诗号。
问道不知何处寻,行路沧茫但由心。海深峰远总成幻,千秋唯奉一剑吟。
《#诗盗#·是个头》:挨踢十年鼠标手,码字百行改用口。若知科技毁身心,不如早当包工头。
改编自霹雳角色“无衣师尹”的诗号。
著书三年倦写字,如今翻书不识志。若知倦书悔前程,无如渔樵未识时。
《#诗盗#·诡龄长生莫沧桑》:红颜易老,英雄殉道,百年沧桑,尽付江潮。
霹雳人物名和歌词拼凑出来的。
《#诗盗#·对联·人生》:上联:世事如棋,乾坤莫测,笑尽英雄。下联:情天有尽,神我无穷,傲笑红尘。
“世事如棋,乾坤莫测,笑尽英雄。”是一页书的出场诗。
“情天有尽,神我无穷”改自号天穷出场诗“天地有尽,神吾无穷”。
“傲笑红尘”是霹雳角色。
《#诗盗#·山坡羊·忘》:人事俱坏,恩仇安在?白云苍狗,回首天涯。
记忆是很脆弱的,如果一件事只有“我”一个人记得,是不是就相当于没有发生过?
有些事情,一转身,就是天涯遥远。
————观世寂莲宇督工
本文仅为个人体悟。
小时候,手笨,不管打什么游戏都老死,但很惊讶地发现每次刚死再复活时,人物身上都是金光闪闪,有一段时间是打不死的无敌状态。过了这个时间后才是拼技术。长大后,觉得这个设定很贴切,和人类的成长过程很像。
每个小孩初生时,身体里有带着母体的保护伞,对很多大人病是免疫的,这股初生的免疫力甚至比母体本身都强大。
青春期的男女,开始出现互相吸引,但同时有一种自我保护意识,制衡作用之下,保证了大部分人身心的健康成长、不至于犯罪等等。这种自我保护意识也是原始强力,个人都不需要特别耗神去运作它,就可以自然起作用。
即使是成熟的男女,也是有类似的原始强力的,比如女人的 ASD。大部分时候,女人即使喜欢一个男人,在要发生亲密关系的时候,都会防御,防止男人觉得自己很随便、很淫荡。这种机制也是自然反应,并非刻意。男人则体现在失恋后的防御上,大部分男人很容易从失恋的痛苦中走出来,因为有一股原始强力,运作起来就可以轻易毁灭不太深入的感情。
但是,好景不长,原始强力都有消失的一天,就说新生儿的保护伞吧,稍微大点,就主要靠自己的修炼了,拼基因和后天营养了。当身心都成熟之后,有些原始强力也消失了,比如女人的 ASD 一次比一次弱。而男人对失恋的抵抗力越来越弱。这时候就要拼情商了,成熟的男人会刻意或被迫减少爱上异性的可能性。
曾经我们有神力相助,人生一帆风顺,把神力拿开的那一天,我们看到很多事情并不是那么自然而然,曾经欠的那些努力,现在要还回去,如果接受了这个设定,就是走向良好的成熟。不接受就是继续活在自己的世界里,也许靠着忽视一些东西,还能继续过着原来那样好像有原始强力帮助自己的生活。
成熟就是失去后的补救。这可好可坏,补救得好,那就是好了……女人的 ASD 一次比一次弱,也许是好事,因为下一次,她更可能爱上的是更成熟的男人,而更成熟的男人是懂这个的,合拍就行了,不用太多掩饰。请想像一下,国内的爱情片画风和欧美的爱情片画风,嗯,好像老外都很快啪啪啪……赫赫。男人也是,越成熟,越不容易陷入爱情,所以失恋了就越痛,这促使男人更谨慎选择,更明白责任与后果。
这么说好像很伟大,为社会稳定而成熟……失去,不一定是坏事。
泥巴娃语录 @ 2016-08-02 08:55:04:年轻人身上总自带一种防御体系,保证自己能在社会中安然成长,聪明人更多会顺应它,违逆它的人往往成为某种程度的失败者。
《#诗盗#·量子邪说》:天地无极,宇宙一体。意识不灭,生死相依。
宇宙是一个整体,死亡只是意识的回归,还会再生,只是丢失了记忆,意识是不灭的。