正常应该执行100次循环的
下面是测试程序:
struct testClass{
testClass():mNumb(1), ptr(NULL){
ptr = new int(1);
}
testClass(const testClass& other){
this->mNumb = other.mNumb;
this->ptr = new int( *(other.ptr));
}
~testClass(){
if (ptr)
{
delete ptr;
ptr = 0;
}
}
int mNumb;
int* ptr;
};
typedef std::vector<testClass> vecArr;
vecArr::iterator it;
vecArr _vecarr;
int main()
{
// _vecarr.reserve(100);
for (int i = 0; i < 100; i++)
{
testClass test1;
_vecarr.push_back( test1 );
testClass test2;
_vecarr.push_back( test2);
printf("vec size: %d\n", _vecarr.size());
it = _vecarr.begin() + (_vecarr.size()/2);
_vecarr.erase(it);
printf("vec size: %d, capacity: %d \n", _vecarr.size(), _vecarr.capacity());
}
printf("The end");
}
其他情况: 1 如果每次循环一push_back() 一次操作的话, 可以正常执行,
2 如果预先分配指定元素的话, 程序会执行到分配大小出中断.
请问问题会出在什么地方呢?
11 个解决方案
#1
什么编译器?
#2
testClass 只有 复制构造,没有赋值重载??
基本上要么都不写,要么都写。只写一个多半是错的。
基本上要么都不写,要么都写。只写一个多半是错的。
#3
请添加赋值操作符重载
#4
正解:
你需要重载=运算符:
testClass&operator=(const testClass& other)
{
mNumb = other.mNumb;
ptr = new int(*(other.ptr)) ;
return *this;
}
vector在添加删除元素的时候会产生复制操作,会调用operator=, 如果你没有重载,编译器默认的操作是内存拷贝,你的深度复制就没起作用。
#5
额, 真是的,非常感谢啊. 我一直在现象上找问题的原因, 却疏忽了原理的基本知识. 下次再使用新东西的时候一定会吃透在用的. 跟了下代码在调用erase时候, 针对后面的元素掉用的是赋值(=)函数, 对于内存分重新分配的时候调用的是拷贝构造函数.
另外有点小迷茫, 为什么访问野指针没有报错,如果该内存恰好可用,就应该执行过去了 而不是阻塞在那里了啊?
#6
额, 真是的,非常感谢啊. 我一直在现象上找问题的原因, 却疏忽了原理的基本知识. 下次再使用新东西的时候一定会吃透在用的. 跟了下代码在调用erase时候, 针对后面的元素掉用的是赋值(=)函数, 对于内存分重新分配的时候调用的是拷贝构造函数.
另外有点小迷茫, 为什么访问野指针没有报错,如果该内存恰好可用,就应该执行过去了 而不是阻塞在那里了啊?
#7
需要看一下实现机制,如果涉及到顺序改变,就会调用operator=, 就有隐患,但也不一定出错。
这和stl的实现方式有关。仅就vc++带的那个stl来说,它有自己的内存管理池,你向vector添加的所有元素都是从那个池中分配的,并且释放时也不是真的释放掉,而释放回到stl自己的内存缓冲池里,因为像vector这样的结构,每次添加和删除以及挪动位置,都会频繁导致新的元素的分配释放。为了避免频繁的内存分配释放和分配造成的时间成本,stl把自己做了管理机制。这就是你说的,为啥释放了还能访问,因为对于系统来说,你的那块内存没有真正释放,还是归你应用程序所有,只是暂时由stl保管。但建议你不要使用这个变量,stl不知道啥时候就把它分配出去了。
这和stl的实现方式有关。仅就vc++带的那个stl来说,它有自己的内存管理池,你向vector添加的所有元素都是从那个池中分配的,并且释放时也不是真的释放掉,而释放回到stl自己的内存缓冲池里,因为像vector这样的结构,每次添加和删除以及挪动位置,都会频繁导致新的元素的分配释放。为了避免频繁的内存分配释放和分配造成的时间成本,stl把自己做了管理机制。这就是你说的,为啥释放了还能访问,因为对于系统来说,你的那块内存没有真正释放,还是归你应用程序所有,只是暂时由stl保管。但建议你不要使用这个变量,stl不知道啥时候就把它分配出去了。
#8
#9
需要看一下实现机制,如果涉及到顺序改变,就会调用operator=, 就有隐患,但也不一定出错。
这和stl的实现方式有关。仅就vc++带的那个stl来说,它有自己的内存管理池,你向vector添加的所有元素都是从那个池中分配的,并且释放时也不是真的释放掉,而释放回到stl自己的内存缓冲池里,因为像vector这样的结构,每次添加和删除以及挪动位置,都会频繁导致新的元素的分配释放。为了避免频繁的内存分配释放和分配造成的时间成本,stl把自己做了管理机制。这就是你说的,为啥释放了还能访问,因为对于系统来说,你的那块内存没有真正释放,还是归你应用程序所有,只是暂时由stl保管。但建议你不要使用这个变量,stl不知道啥时候就把它分配出去了。
我只知道sgi的是用内存池的
#11
6楼正解~~
#1
什么编译器?
#2
testClass 只有 复制构造,没有赋值重载??
基本上要么都不写,要么都写。只写一个多半是错的。
基本上要么都不写,要么都写。只写一个多半是错的。
#3
请添加赋值操作符重载
#4
testClass 只有 复制构造,没有赋值重载??
基本上要么都不写,要么都写。只写一个多半是错的。
正解:
你需要重载=运算符:
testClass&operator=(const testClass& other)
{
mNumb = other.mNumb;
ptr = new int(*(other.ptr)) ;
return *this;
}
vector在添加删除元素的时候会产生复制操作,会调用operator=, 如果你没有重载,编译器默认的操作是内存拷贝,你的深度复制就没起作用。
#5
testClass 只有 复制构造,没有赋值重载??
基本上要么都不写,要么都写。只写一个多半是错的。
额, 真是的,非常感谢啊. 我一直在现象上找问题的原因, 却疏忽了原理的基本知识. 下次再使用新东西的时候一定会吃透在用的. 跟了下代码在调用erase时候, 针对后面的元素掉用的是赋值(=)函数, 对于内存分重新分配的时候调用的是拷贝构造函数.
另外有点小迷茫, 为什么访问野指针没有报错,如果该内存恰好可用,就应该执行过去了 而不是阻塞在那里了啊?
#6
testClass 只有 复制构造,没有赋值重载??
基本上要么都不写,要么都写。只写一个多半是错的。
正解:
你需要重载=运算符:
testClass&operator=(const testClass& other)
{
mNumb = other.mNumb;
ptr = new int(*(other.ptr)) ;
return *this;
}
vector在添加删除元素的时候会产生复制操作,会调用operator=, 如果你没有重载,编译器默认的操作是内存拷贝,你的深度复制就没起作用。
额, 真是的,非常感谢啊. 我一直在现象上找问题的原因, 却疏忽了原理的基本知识. 下次再使用新东西的时候一定会吃透在用的. 跟了下代码在调用erase时候, 针对后面的元素掉用的是赋值(=)函数, 对于内存分重新分配的时候调用的是拷贝构造函数.
另外有点小迷茫, 为什么访问野指针没有报错,如果该内存恰好可用,就应该执行过去了 而不是阻塞在那里了啊?
#7
需要看一下实现机制,如果涉及到顺序改变,就会调用operator=, 就有隐患,但也不一定出错。
这和stl的实现方式有关。仅就vc++带的那个stl来说,它有自己的内存管理池,你向vector添加的所有元素都是从那个池中分配的,并且释放时也不是真的释放掉,而释放回到stl自己的内存缓冲池里,因为像vector这样的结构,每次添加和删除以及挪动位置,都会频繁导致新的元素的分配释放。为了避免频繁的内存分配释放和分配造成的时间成本,stl把自己做了管理机制。这就是你说的,为啥释放了还能访问,因为对于系统来说,你的那块内存没有真正释放,还是归你应用程序所有,只是暂时由stl保管。但建议你不要使用这个变量,stl不知道啥时候就把它分配出去了。
这和stl的实现方式有关。仅就vc++带的那个stl来说,它有自己的内存管理池,你向vector添加的所有元素都是从那个池中分配的,并且释放时也不是真的释放掉,而释放回到stl自己的内存缓冲池里,因为像vector这样的结构,每次添加和删除以及挪动位置,都会频繁导致新的元素的分配释放。为了避免频繁的内存分配释放和分配造成的时间成本,stl把自己做了管理机制。这就是你说的,为啥释放了还能访问,因为对于系统来说,你的那块内存没有真正释放,还是归你应用程序所有,只是暂时由stl保管。但建议你不要使用这个变量,stl不知道啥时候就把它分配出去了。
#8
#9
需要看一下实现机制,如果涉及到顺序改变,就会调用operator=, 就有隐患,但也不一定出错。
这和stl的实现方式有关。仅就vc++带的那个stl来说,它有自己的内存管理池,你向vector添加的所有元素都是从那个池中分配的,并且释放时也不是真的释放掉,而释放回到stl自己的内存缓冲池里,因为像vector这样的结构,每次添加和删除以及挪动位置,都会频繁导致新的元素的分配释放。为了避免频繁的内存分配释放和分配造成的时间成本,stl把自己做了管理机制。这就是你说的,为啥释放了还能访问,因为对于系统来说,你的那块内存没有真正释放,还是归你应用程序所有,只是暂时由stl保管。但建议你不要使用这个变量,stl不知道啥时候就把它分配出去了。
我只知道sgi的是用内存池的
#10
如果你的编译器版本够新,支持C++11的话,可能没必要重载operator=().
仅供参考
仅供参考
#11
6楼正解~~