vector.push_back() 也会报错???

C++语言 码拜 10年前 (2015-05-11) 4474次浏览 0个评论

最近在运行一个较大的程序,内存占用可能有点多,其中在vector.push_back()处报错,感到很奇怪。用g++ -std=c++11编译。
下面是与报错相关的部分。
vector<int> KATT;
KATT.clear();
int KATT2;
……
……
……
KATT.push_back(KATT2);

程序输出及报错信息:
KATT2 =  -1
KATT.size() =  16
*** Error in `./a.out””: free(): invalid next size (fast): 0x00000000020554b0 ***
Aborted (core dumped)

补充一下,此时
KATT.capacity() = 16;

难道是这个vector的内存用满了? 可是我记得vector是可以自己申请更多内存的,我自己并没有给它reserve 一个固定大小的内存

继续补充,我加入了以下控制,没起到作用,不知道问题出在哪儿?

    cout << “break = ” << ” ” << 2.22222 << endl;
    cout << “KATT.size() = ” << ” ” << KATT.size() << endl;
    cout << “KATT.capacity() = ” << ” ” << KATT.capacity() << endl;

    if (KATT.size() == KATT.capacity())
    {
        KATT.reserve(KATT.capacity() * 2);
    cout << “KATT.capacity() = ” << ” ” << KATT.capacity() << endl;
    }

                    KATT.push_back(KATT2);

    //……….Test block
    cout << “KINT = ” << ” ” << 2.33333 << endl;

输出:
break =  2.22222
KATT.size() =  2
KATT.capacity() =  2
*** Error in `./a.out””: free(): invalid next size (fast): 0x00000000022793d0 ***
Aborted (core dumped)

内存不足吧。
我理解向量容器使用的内存是连续的。
比如说刚开始只有16*4 byte大小的空间,
如果再向里面push, 他自动回创建一个更大的空间, 比如是16*4*2
将原来的数据拷贝到新的空间, 原来的删除掉。
如果申请新的空间不足, 或没有连续空间可以使用,
就申请不到新内存。
引用 4 楼 lyyslsw 的回复:

我理解向量容器使用的内存是连续的。
比如说刚开始只有16*4 byte大小的空间,
如果再向里面push, 他自动回创建一个更大的空间, 比如是16*4*2
将原来的数据拷贝到新的空间, 原来的删除掉。
如果申请新的空间不足, 或没有连续空间可以使用,
就申请不到新内存。

肯定不是这样的,这样的话效率不是很低了

应该不是内存不足的问题,才两个元素就内存不足应该不会,具体是什么这样也看不出,楼主新建个工程试下
引用 5 楼 paschen 的回复:
Quote: 引用 4 楼 lyyslsw 的回复:

我理解向量容器使用的内存是连续的。
比如说刚开始只有16*4 byte大小的空间,
如果再向里面push, 他自动回创建一个更大的空间, 比如是16*4*2
将原来的数据拷贝到新的空间, 原来的删除掉。
如果申请新的空间不足, 或没有连续空间可以使用,
就申请不到新内存。

肯定不是这样的,这样的话效率不是很低了

应该是这样的,vector 如果总改变大小的话,效率确实不是很高

5分
这个应该是你其他某个地方的内存访问越界了,覆盖到了 vector 申请的内存,导致里面一些用于内存管理的数据被破坏,然后释放内存的时候就出错了。这个错误是在释放的时候,而不是申请的时候,所以和内存不足没什么关系。
5分
我昨天也遇到过相似的问题,可以肯定的是问题不是vector.push_back()错!绝对不是!全都是内存越界了,有其他地方冲洗掉了原来的vector的内存。
比如我昨天是因为手贱使用了一个strncpy函数的时候字节写错了。
char ctemp[512] = {0};
strncpy(ctemp, str.c_str(), 1024);
所以后面512个字节就被冲成了NULL,至于为什么刚好冲了vector,我没去仔细研究内存块。
引用 3 楼 ml232528 的回复:

内存不足吧。

内存应该是足够的,本机有4G内存

引用 7 楼 renyt123 的回复:
Quote: 引用 5 楼 paschen 的回复:
Quote: 引用 4 楼 lyyslsw 的回复:

我理解向量容器使用的内存是连续的。
比如说刚开始只有16*4 byte大小的空间,
如果再向里面push, 他自动回创建一个更大的空间, 比如是16*4*2
将原来的数据拷贝到新的空间, 原来的删除掉。
如果申请新的空间不足, 或没有连续空间可以使用,
就申请不到新内存。

肯定不是这样的,这样的话效率不是很低了

应该是这样的,vector 如果总改变大小的话,效率确实不是很高

我测试过,vector确实是先有固定大小,当要push的时候才会申请更多(一般是2倍当前大小)的内存。如果程序不是太大,效率就显得有些低了

可能是8楼和9楼说的,内存越界了,毕竟报错是 free()。
我后来给所有的vector提前分配了内存就没有这个问题了
KATT.clear();
KATT.reserve(1000);    // 先申请1000个该类型大小的内存

但是我觉得奇怪的是,在整个程序中,我并没有使用 free(), 但是使用过用vector做函数形参,不知道是不是调用函数后程序自己把形参的内存freele 。可是为何它在其他地方没有报错,就只是在KATT这个vector这里报错了呢?

5分
vector 扩展内存的时候有可能会先 free 掉之前申请的内存. 你这样提前分配大内存来避免错误并没有结局你代码的 BUG,隐藏起来可能导致更多的逻辑错误
引用 13 楼 adlay 的回复:

vector 扩展内存的时候有可能会先 free 掉之前申请的内存. 你这样提前分配大内存来避免错误并没有结局你代码的 BUG,隐藏起来可能导致更多的逻辑错误

恩,有道理。我只能通过打印输出确定错误发生的地方,更深入的跟内存相关的,我不懂程序到底怎么出错的。你知道怎么调试吗?

5分
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。
引用 15 楼 zhao4zhong1 的回复:

崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。

你用的是什么编译器和调试软件,vc 吗?我在Ubuntu 下用的 g++ 和 gdb,gdb 目前只会几个初级的命令。。。

引用 15 楼 zhao4zhong1 的回复:

崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。

好的,我看到了用 bt

引用 17 楼 wseektime 的回复:
Quote: 引用 15 楼 zhao4zhong1 的回复:

崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。

好的,我看到了用 bt

gdb调试的话,可以观察是谁擦写了某段特定的内存,非常方便,也非常容易定位问题

这个帖子结了,欢迎大家转到另一个帖子讨论,那边分数多 。讨论到了怎么确定 程序自己 double free 了。
http://bbs.csdn.net/topics/391042217
引用 18 楼 yangyunzhao 的回复:
Quote: 引用 17 楼 wseektime 的回复:
Quote: 引用 15 楼 zhao4zhong1 的回复:

崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。

好的,我看到了用 bt

gdb调试的话,可以观察是谁擦写了某段特定的内存,非常方便,也非常容易定位问题

2. 设置观察点(WatchPoint)
观察点一般用来观察某个表达式(变量也是一种表达式)的值是否变化了。如果有变化,马上停住程序。有下面的几种方法来设置观察点:
watch <expr>
为表达式(变量)expr设置一个观察点。一旦表达式值有变化时,马上停住程序。
rwatch <expr>
当表达式(变量)expr被读时,停住程序。
awatch <expr>
当表达式(变量)的值被读或被写时,停住程序。
info watchpoints
列出当前设置的所有观察点。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明vector.push_back() 也会报错???
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!