C++ primer第十八章
C++ primer第十八章求助!
今天在学习C++ primer的时候,实践了一下第十八章的641页的CacheObject这个类,最后一运行就是double free or curuption
小弟写的代码如下
CacheObject.h
CacheObject.cc
子类化CacheObject
person.h
main.cc
最后运行结果就成这样了。。。
./person
1
qeesung
2
season
2
*** glibc detected *** ./person: double free or corruption (fasttop): 0x085eb038 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75b12)[0xb7587b12]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb778451f]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1b)[0xb776b99b]
/usr/lib/i386-linux-gnu/libstdc++.so.6(+0x909dc)[0xb776b9dc]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSsD1Ev+0x2e)[0xb776ba4e]
./person[0x8048d87]
./person[0x8048b51]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb752b4d3]
./person[0x8048891]
======= Memory map: ========
。。。
求助各位大神,这是哪里有问题啊???
------解决思路----------------------
这个应该是Linux下面string类的实现问题。
Person3被析构了两次,它的成员name也被析构了两次。
从函数堆栈来看就是name被析构了两次造成的。
不过在vs2008下面没有问题,这是VS和Linux中STL实现不一致造成的吧。
你调试跟一下string的析构函数做了什么就知道了。
今天在学习C++ primer的时候,实践了一下第十八章的641页的CacheObject这个类,最后一运行就是double free or curuption
小弟写的代码如下
CacheObject.h
#ifndef _CACHEOBJ_H
#define _CACHEOBJ_H
#include <iostream>
#include <memory>
template <typename T>
class CacheObj
{
public:
void * operator new(std::size_t size);
void operator delete(void * p , std::size_t size);
virtual ~CacheObj(){}
protected:
T * next;
private:
static void addToList(T *);//将链表节点元素添加到链表里面
static T * freeList;//表头指针
static const std::size_t chunk;//预计分配元素大小
static std::allocator<T> allocMem;//用来分配内存的
};
#include "cacheObj.cc"
#endif
CacheObject.cc
#include <stdexcept>
template <typename T> T * CacheObj<T>::freeList=0;
template <typename T> const std::size_t CacheObj<T>::chunk=20;
template <typename T> std::allocator<T> CacheObj<T>::allocMem;
template <typename T>
void * CacheObj<T>::operator new(std::size_t size)
{
if(size != sizeof(T))
throw std::runtime_error("CacheObj: wrong size object in operator new");
//开始分配元素
if(freeList == NULL)
{
T * array = CacheObj<T>::allocMem.allocate(chunk);
for (std::size_t i = 0; i < chunk; ++i)
{
addToList(&array[i]);
}
}
//返回分配得到的内存指针
T * retPtr=freeList;
freeList = freeList->CacheObj<T>::next;
return retPtr;
}
template <typename T>
void CacheObj<T>::operator delete(void * ptr , std::size_t /*size*/)
{
//调用此函数之前,已经被析构了
if(ptr==NULL)
return;
addToList(static_cast<T*>(ptr));
}
template <typename T>
void CacheObj<T>::addToList(T * ptr)
{
//将元素添加到表头之后
ptr->CacheObj<T>::next = freeList;
freeList=ptr;
}
子类化CacheObject
person.h
#ifndef _PERSON_H
#define _PERSON_H
#include "cacheObj.h"
#include <iostream>
#include <string>
class Person : public CacheObj<Person>
{
public:
Person(const std::string _name="qeesung" , const int _id=1):name(_name),id(_id){personCount++;}
int getId() const{return id;}
std::string getName() const {return name;}
static std::size_t getPersonCount(){return personCount;}
~Person(){--personCount;}
private:
static std::size_t personCount;
std::string name;
int id;
};
std::size_t Person::personCount=0;
#endif
main.cc
#include <iostream>
#include "person.h"
using namespace std;
int main(int argc, char const *argv[])
{
Person person1;
Person person2("season",2);
Person person3("weepinside",3);
person3.~Person();
cout<<person1.getId()<<endl;
cout<<person1.getName()<<endl;
cout<<person2.getId()<<endl;
cout<<person2.getName()<<endl;
cout<<Person::getPersonCount()<<endl;
return 0;
}
最后运行结果就成这样了。。。
./person
1
qeesung
2
season
2
*** glibc detected *** ./person: double free or corruption (fasttop): 0x085eb038 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75b12)[0xb7587b12]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZdlPv+0x1f)[0xb778451f]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSs4_Rep10_M_destroyERKSaIcE+0x1b)[0xb776b99b]
/usr/lib/i386-linux-gnu/libstdc++.so.6(+0x909dc)[0xb776b9dc]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSsD1Ev+0x2e)[0xb776ba4e]
./person[0x8048d87]
./person[0x8048b51]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb752b4d3]
./person[0x8048891]
======= Memory map: ========
。。。
求助各位大神,这是哪里有问题啊???
------解决思路----------------------
这个应该是Linux下面string类的实现问题。
Person3被析构了两次,它的成员name也被析构了两次。
从函数堆栈来看就是name被析构了两次造成的。
不过在vs2008下面没有问题,这是VS和Linux中STL实现不一致造成的吧。
你调试跟一下string的析构函数做了什么就知道了。