求解为什么会报错,代码如下

zhl11a 2013-12-24 09:49:47
#include<iostream>
#include<string.h>
#include<assert.h>
#include<stdio.h>
#include<memory>
#include<vector>
#include<deque>

using namespace std;

class buffer
{
private:
deque<vector<char>*> _blocks;
public:
buffer();
~buffer();
char *getData();
bool addData(const char *id,const char *message);
};

buffer::buffer()
{
}

buffer::~buffer()
{
for(int a = 0; a <= _blocks.size(); a++)
{
cout<<_blocks.size()<<endl;
delete _blocks[a];
}
}

char *buffer::getData() //申请了内存需要自己释放
{
if(!_blocks[0]->empty())
{
char *data =new char(_blocks[0]->size());
memmove(data, &_blocks[0]->at(0), _blocks[0]->size());

delete _blocks[0];
_blocks.pop_front();
return data;
}
}

bool buffer::addData(const char *id,const char *message)
{
assert(id != NULL && message != NULL);
assert(strlen(id) < 19);

vector<char> *data = new vector<char>(message,message+strlen(message)+1);
_blocks.push_back(data);
return true;
}

//测试
int main()
{
buffer *read = new buffer;
if(read->addData("55", "fuck") == false) std::cout<<"add erro"<<std::endl;
if(read->addData("55", "55safsdafsad") == false) std::cout<<"add erro"<<std::endl;
std::cout<<"fdsff"<<std::endl;
char *data1 = read->getData();
std::cout<<data1<<""<<std::endl;
// delete data1; //这样不会报错
char *data2 = read->getData();
std::cout<<data2<<std::endl;
// printf("%p",data);
delete data2, data1; //这样会有 invalid fastbin entry (free): 0x0878d288 ***的错误
delete read;
}

如题,在第一次调用成员函数时,立马删除指针再次调用不会出错。但是如果不立刻删除,进行第二次调用成员函数,就会出错,求解是为什么
...全文
587 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhl11a 2013-12-26
  • 打赏
  • 举报
回复
引用 27 楼 u011546766 的回复:
[quote=引用 10 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! 单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
俗话说:授人鱼不如授人以渔。 大哥这回复应该拿满分[/quote] 大哥这回复确实是正确的,也是值得我们学习的,但是鄙人目前水平略显不足。而且这些话我看见过很多次了。 所以,我认为应该给指出问题的人给分。
StuClass 2013-12-24
  • 打赏
  • 举报
回复
应该就是“delete不能delete一系列指针”的问题
赵4老师 2013-12-24
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! 单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
lm_whales 2013-12-24
  • 打赏
  • 举报
回复
1)deque<vector<char>*> _blocks;???? 这个程序,逻辑混乱,先整理下思路,调整下程序,再调试。 vector<char> 主要就是一个指针而已,没有必要用vector<char>* 需要的话vector <vector<char> > 足矣。 另外字符串可以用 string ,vector< string >; 2)getData 这样写法,绝对不是好的代码,返回的这个指针,一不小心就丢失了。 3)delete 不能 delete 一系列 指针,一个表达式只能 delete 1个指针。 delete data2, data1; //这是逗号表达式,值为data1,只delete 一个指针data2; <==> delete data2; //先执行 delete data2; data1; //后执行 data1;
zhl11a 2013-12-24
  • 打赏
  • 举报
回复
引用 7 楼 StuClass 的回复:
你的类成员函数里面的new,在你的析构函数里面已经释放了,你在delete read的时候,析构函数会去释放那些空间,所以delete data1,data2是多余了。当执行delete read的时候就会去释放已经释放了的空间,就会报内存访问的问题
绝对不是,析构函数那儿有对_block的size大小判断的,只是贴上来的时候不小心多打了一个等号
StuClass 2013-12-24
  • 打赏
  • 举报
回复
你的类成员函数里面的new,在你的析构函数里面已经释放了,你在delete read的时候,析构函数会去释放那些空间,所以delete data1,data2是多余了。当执行delete read的时候就会去释放已经释放了的空间,就会报内存访问的问题
zhl11a 2013-12-24
  • 打赏
  • 举报
回复
引用 5 楼 StuClass 的回复:
你只用了一个new,就只需要一个delete
没有,我调用了getdata成员函数2次,所以用了2次new
StuClass 2013-12-24
  • 打赏
  • 举报
回复
你只用了一个new,就只需要一个delete
zhl11a 2013-12-24
  • 打赏
  • 举报
回复
引用 3 楼 zhl11a 的回复:
[quote=引用 2 楼 wb117908406 的回复:] 把所有申请内存地址打印出来,估计两个指针指向一块内存
fdsff 0x9db32b0 fuck 0x9db3268 不是同一块[/quote] 报错如下invalid fastbin entry (free): 0x09db3288
zhl11a 2013-12-24
  • 打赏
  • 举报
回复
引用 2 楼 wb117908406 的回复:
把所有申请内存地址打印出来,估计两个指针指向一块内存
fdsff 0x9db32b0 fuck 0x9db3268 不是同一块
wb_rock 2013-12-24
  • 打赏
  • 举报
回复
把所有申请内存地址打印出来,估计两个指针指向一块内存
zhl11a 2013-12-24
  • 打赏
  • 举报
回复
一只小水鱼 2013-12-24
  • 打赏
  • 举报
回复
引用 10 楼 zhao4zhong1 的回复:
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! 单步类的实例“构造”或“复制”或“作为函数参数”或“作为函数返回值返回”或“参加各种运算”或“退出作用域”的语句对应的汇编代码几步后,就会来到该类的“构造函数”或“复制构造函数”或“运算符重载”或“析构函数”对应的C/C++源代码处。 VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。 (Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
俗话说:授人鱼不如授人以渔。 大哥这回复应该拿满分
大奶兔白糖 2013-12-24
  • 打赏
  • 举报
回复
哦,明白了。
zhl11a 2013-12-24
  • 打赏
  • 举报
回复
引用 24 楼 bijiaoben 的回复:
而且data2的结果没打印出来啊 char *data2 = read->getData(); std::cout<<data2<<std::endl; ->没看到输出啊 我觉得你是在 delete _blocks[0]; _blocks.pop_front(); 这段代码中出了问题,感觉getData还没有返回。
没有,是getdata使用()代替了[]直接导致分配的内存只有一个字节,然后memmove导致内存越界了
大奶兔白糖 2013-12-24
  • 打赏
  • 举报
回复
而且data2的结果没打印出来啊 char *data2 = read->getData(); std::cout<<data2<<std::endl; ->没看到输出啊 我觉得你是在 delete _blocks[0]; _blocks.pop_front(); 这段代码中出了问题,感觉getData还没有返回。
zhl11a 2013-12-24
  • 打赏
  • 举报
回复
引用 21 楼 bijiaoben 的回复:
[quote=引用 18 楼 zhl11a 的回复:] [quote=引用 17 楼 bijiaoben 的回复:] [quote=引用 16 楼 zhl11a 的回复:]
fdsff
0x9d542b0
fuck
0x9d54268
*** glibc detected *** ./buffe: invalid fastbin entry (free): 0x09d54288 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6c0c1)[0x4440c1]
/lib/libc.so.6(+0x6d930)[0x445930]
/lib/libc.so.6(cfree+0x6d)[0x448a1d]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x397441]
./buffe[0x8048cf8]
./buffe[0x8048f6b]
/lib/libc.so.6(__libc_start_main+0xe7)[0x3eece7]
./buffe[0x80489e1]
======= Memory map: ========
001a1000-001bd000 r-xp 00000000 08:01 1053996    /lib/ld-2.12.1.so
001bd000-001be000 r--p 0001b000 08:01 1053996    /lib/ld-2.12.1.so
001be000-001bf000 rw-p 0001c000 08:01 1053996    /lib/ld-2.12.1.so
002ed000-003cc000 r-xp 00000000 08:01 134898     /usr/lib/libstdc++.so.6.0.14
003cc000-003d0000 r--p 000de000 08:01 134898     /usr/lib/libstdc++.so.6.0.14
003d0000-003d1000 rw-p 000e2000 08:01 134898     /usr/lib/libstdc++.so.6.0.14
003d1000-003d8000 rw-p 00000000 00:00 0 
003d8000-0052f000 r-xp 00000000 08:01 1054202    /lib/libc-2.12.1.so
0052f000-00531000 r--p 00157000 08:01 1054202    /lib/libc-2.12.1.so
00531000-00532000 rw-p 00159000 08:01 1054202    /lib/libc-2.12.1.so
00532000-00535000 rw-p 00000000 00:00 0 
006f5000-006f6000 r-xp 00000000 00:00 0          [vdso]
006fb000-0071f000 r-xp 00000000 08:01 1054200    /lib/libm-2.12.1.so
0071f000-00720000 r--p 00023000 08:01 1054200    /lib/libm-2.12.1.so
00720000-00721000 rw-p 00024000 08:01 1054200    /lib/libm-2.12.1.so
00df9000-00e13000 r-xp 00000000 08:01 1051186    /lib/libgcc_s.so.1
00e13000-00e14000 r--p 00019000 08:01 1051186    /lib/libgcc_s.so.1
00e14000-00e15000 rw-p 0001a000 08:01 1051186    /lib/libgcc_s.so.1
08048000-0804c000 r-xp 00000000 00:15 110        /mnt/hgfs/program/buffe
0804c000-0804d000 r--p 00003000 00:15 110        /mnt/hgfs/program/buffe
0804d000-0804e000 rw-p 00004000 00:15 110        /mnt/hgfs/program/buffe
09d54000-09d75000 rw-p 00000000 00:00 0          [heap]
b7600000-b7621000 rw-p 00000000 00:00 0 
b7621000-b7700000 ---p 00000000 00:00 0 
b7709000-b770c000 rw-p 00000000 00:00 0 
b771b000-b771e000 rw-p 00000000 00:00 0 
bfe68000-bfe89000 rw-p 00000000 00:00 0          [stack]
g++编译后运行出错信息如下
楼主能不能贴一下你最新运行的代码?因为在你贴的代码中,我没有看到在哪里有打印地址的操作啊。。[/quote] 在15楼的41行有打印地址操作[/quote] 楼主,一个奇怪的问题,为什么分到的地址是0x9d54268,而去释放的时候地址变成了0x09d54288,多了32个byte。。。[/quote] 粗心的错,本来是想new一个数组的,结果[]打错成()。
zhl11a 2013-12-24
  • 打赏
  • 举报
回复
引用 20 楼 yipeng1125 的回复:
把 char *data =new char(_blocks[0]->size()); 改成 char *data = new char[ _blocks[0]->size()]; delete[] data1; delete[] data2; 试试
!!! 我对自己无语了,原来是括号打错了!!!!! 粗心的教训!!! 谢谢层主了!
大奶兔白糖 2013-12-24
  • 打赏
  • 举报
回复
引用 18 楼 zhl11a 的回复:
[quote=引用 17 楼 bijiaoben 的回复:] [quote=引用 16 楼 zhl11a 的回复:]
fdsff
0x9d542b0
fuck
0x9d54268
*** glibc detected *** ./buffe: invalid fastbin entry (free): 0x09d54288 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6c0c1)[0x4440c1]
/lib/libc.so.6(+0x6d930)[0x445930]
/lib/libc.so.6(cfree+0x6d)[0x448a1d]
/usr/lib/libstdc++.so.6(_ZdlPv+0x21)[0x397441]
./buffe[0x8048cf8]
./buffe[0x8048f6b]
/lib/libc.so.6(__libc_start_main+0xe7)[0x3eece7]
./buffe[0x80489e1]
======= Memory map: ========
001a1000-001bd000 r-xp 00000000 08:01 1053996    /lib/ld-2.12.1.so
001bd000-001be000 r--p 0001b000 08:01 1053996    /lib/ld-2.12.1.so
001be000-001bf000 rw-p 0001c000 08:01 1053996    /lib/ld-2.12.1.so
002ed000-003cc000 r-xp 00000000 08:01 134898     /usr/lib/libstdc++.so.6.0.14
003cc000-003d0000 r--p 000de000 08:01 134898     /usr/lib/libstdc++.so.6.0.14
003d0000-003d1000 rw-p 000e2000 08:01 134898     /usr/lib/libstdc++.so.6.0.14
003d1000-003d8000 rw-p 00000000 00:00 0 
003d8000-0052f000 r-xp 00000000 08:01 1054202    /lib/libc-2.12.1.so
0052f000-00531000 r--p 00157000 08:01 1054202    /lib/libc-2.12.1.so
00531000-00532000 rw-p 00159000 08:01 1054202    /lib/libc-2.12.1.so
00532000-00535000 rw-p 00000000 00:00 0 
006f5000-006f6000 r-xp 00000000 00:00 0          [vdso]
006fb000-0071f000 r-xp 00000000 08:01 1054200    /lib/libm-2.12.1.so
0071f000-00720000 r--p 00023000 08:01 1054200    /lib/libm-2.12.1.so
00720000-00721000 rw-p 00024000 08:01 1054200    /lib/libm-2.12.1.so
00df9000-00e13000 r-xp 00000000 08:01 1051186    /lib/libgcc_s.so.1
00e13000-00e14000 r--p 00019000 08:01 1051186    /lib/libgcc_s.so.1
00e14000-00e15000 rw-p 0001a000 08:01 1051186    /lib/libgcc_s.so.1
08048000-0804c000 r-xp 00000000 00:15 110        /mnt/hgfs/program/buffe
0804c000-0804d000 r--p 00003000 00:15 110        /mnt/hgfs/program/buffe
0804d000-0804e000 rw-p 00004000 00:15 110        /mnt/hgfs/program/buffe
09d54000-09d75000 rw-p 00000000 00:00 0          [heap]
b7600000-b7621000 rw-p 00000000 00:00 0 
b7621000-b7700000 ---p 00000000 00:00 0 
b7709000-b770c000 rw-p 00000000 00:00 0 
b771b000-b771e000 rw-p 00000000 00:00 0 
bfe68000-bfe89000 rw-p 00000000 00:00 0          [stack]
g++编译后运行出错信息如下
楼主能不能贴一下你最新运行的代码?因为在你贴的代码中,我没有看到在哪里有打印地址的操作啊。。[/quote] 在15楼的41行有打印地址操作[/quote] 楼主,一个奇怪的问题,为什么分到的地址是0x9d54268,而去释放的时候地址变成了0x09d54288,多了32个byte。。。
yipeng1125 2013-12-24
  • 打赏
  • 举报
回复
把 char *data =new char(_blocks[0]->size()); 改成 char *data = new char[ _blocks[0]->size()]; delete[] data1; delete[] data2; 试试
加载更多回复(8)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧