C/C++bug记录

记录一些比较难解决,需要查资料思考,第一眼看不出的bug

C

环境:Ubuntu 16.04
编译器:GCC

goto语句标签之间的区域不能存在声明语句

用C语言在Linux上写轮询的时候,遇见的err。

block.c: In function ‘main’:
block.c:20:5: error: a label can only be part of a statement and a declaration is not a statement
     char buf[20];
     ^
block.c:21:5: error: expected expression before ‘int’
     int len = read(fd, buf, 20);
     ^
block.c:22:9: error: ‘len’ undeclared (first use in this function)
     if (len < 0)
         ^
block.c:22:9: note: each undeclared identifier is reported only once for each function it appears in

err中特别提到了:

a label can only be part of a statement and a declaration is not a statement

于是我试着将所有在goto标签之间的声明全部移除去,结果编译通过了。之后又实验了一下,也是如此。
解决方法: 将所有在goto标签之间的声明全部移除到标签之外。

C++

构造函数初始化列表初始化先后顺序导致的问题

环境:Ubuntu 16.04
编译器: g++

数据成员定义先后顺序为:
在这里插入图片描述
构造函数初始化列表:
在这里插入图片描述

ERR:
在这里插入图片描述
产生原因:主要原因为系统内存,无法满足程序内存分配需求。

解决:
起初这个让人非常疑惑,我根本没有分配多大内存,怎么会导致系统内存不够用呢?
困扰了我许久之后。我在每个分配内存的地方都用cout打印一个信息观察从那个地方开始出现问题。
在这里插入图片描述
定位到出问题最开始处,源码如下:
在这里插入图片描述
显然必定是构造函数分配内存时出现了问题,分配了一个系统无法接下的内存量。
构造函数内存分配代码如下:
在这里插入图片描述
看到这里的一瞬间我明白了,一定是类中参数定义的先后顺序问题。_pstr成员先于_size成员一不在类中定义。初始化列表中会根据类中成员数据定义的先后顺序进行初始化,那么_size应该是被编译器设置为0xCCCCCCCCCCCCCC总之全部填充C。这不得了,这个内存就太惊人了。我记得Linux似乎只是利用了64系统的48位寻址。

一个关于移动语义导致问题的思考。

环境:Ubuntu 16.04
编译器: g++

在这里插入图片描述
报错:

Error in `./a.out’: double free or corruption (fasttop): 0x00000000019750b0

此处毫无疑问是多次释放同一块内存,最终定位到此处。
在这里插入图片描述
多次释放内存在我的经验中,有时候将弃用指针置空可能会观察到其他现象,但这里直接就不报错了,不清楚为什么这样,如下:
在这里插入图片描述
在这里插入图片描述

于是我我想问题可能出在std::move的实现上,所以跟进查看std::move源码,并且在我的印象中std::move应该是强制类型转换,将目标强制转为右值,并不在建议使用。
查阅std::move源码如下:
在这里插入图片描述
可以看见,如果目标类型有reference属性,则摘除并使用static_cast强制转换为去引用类型的右值。并且这里可以知道并没有调用任何其他函数。

仔细思考后,突然想通了。感叹自己实在太笨,std::move中的确是强制转换也没有调用其他函数释放目标,但是rhs._pstr的值并不一定改变了变为了野指针,那么rhs很有可能会调用自己的析构函(实现为_pstr非空delete)数释放rhs._pstr指向的堆内存,现在rhs._pstr自己指向的堆空间交给this._pstr,this同样会调用自己的析构函数那么就造成了多次delete同一块内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值