下午好,我正在尝试删除一个由指针数组组成的C++类成员变量。以下是代码的摘录:
class NFA {
public:
dict<tuple2<__ss_int, __ss_int> *, dict<str *, __shedskin__::set<tuple2<__ss_int, __ss_int> *> *> *> *transitions;
auto_vector< dict<str *, set<tuple2<__ss_int, __ss_int> *> *> > *tmpautovector;
NFA() {}
~NFA() { delete this->tmpautovector
NFA(tuple2<__ss_int, __ss_int> *start_state) {
this->__class__ = cl_NFA;
__init__(start_state);
}
void *add_transition(tuple2<__ss_int, __ss_int> *src, str *input, tuple2<__ss_int, __ss_int> *dest);
}
void *NFA::add_transition(tuple2<__ss_int, __ss_int> *src, str *input, tuple2<__ss_int, __ss_int> *dest) {
dict<str *, set<tuple2<__ss_int, __ss_int> *> *> *tmpdict;
if ((!(this->transitions)->__contains__(src))) {
tmpdict = new dict<str *, set<tuple2<__ss_int, __ss_int> *> *>();
this->transitions->__setitem__(src, tmpdict);
tmpautovector->push_back(tmpdict);
}
return NULL;
}我尝试使用auto_vector类来存储一个指针数组。下面是auto_vector类的一些函数。这个类的文档说这不是auto_ptr的STL向量。强烈建议使用STL向量来存储auto_ptr>当我访问auto_vector::operator成员函数时,我总是得到一个分段错误> GDB堆栈跟踪,如下所示显示了分段错误。我想知道是否有可能修复这个分段错误,或者是否有更好的方法来删除由指针数组组成的成员变量。谢谢。
// auto_vector.h
// This file is (C) 2002-2004 Royce Mitchell III
// and released under the LGPL & BSD licenses
#ifndef AUTO_VECTOR_H
#define AUTO_VECTOR_H
#include <sys/types.h>
#include <memory>
template<class T>
class auto_vector
{
public:
explicit auto_vector ( size_t capacity = 0 )
: _arr(0), _capacity(0), _end(0)
{
if ( capacity != 0 )
_arr = new std::auto_ptr<T>[capacity];
_capacity = capacity;
}
~auto_vector()
{
delete []_arr;
}
size_t size() const
{
return _end;
}
const std::auto_ptr<T>& operator [] ( size_t i )
{
return _arr[i];
}
std::auto_ptr<T>& operator [] ( size_t i )
{
return _arr[i];
}
void push_back ( std::auto_ptr<T>& p )
{
reserve ( _end + 1 );
_arr[_end++] = p;
}
void push_back ( T * p )
{
reserve ( _end + 1 );
std::auto_ptr<T> tmp(p);
_arr[_end++] = tmp;
//GCC is pedantic, this is an error.
//_arr[_end++] = auto_ptr<T>(p);
}
void reserve ( size_t reqCapacity )
{
if ( reqCapacity <= _capacity )
return;
size_t newCapacity = 2 * _capacity;
if ( reqCapacity > newCapacity )
newCapacity = reqCapacity;
// allocate new array
std::auto_ptr<T> * arrNew = new std::auto_ptr<T> [newCapacity];
// transfer all entries
for ( size_t i = 0; i < _capacity; ++i )
arrNew[i] = _arr[i];
_capacity = newCapacity;
// free old memory
delete[] _arr;
// substitute new array for old array
_arr = arrNew;
}
private:
std::auto_ptr<T> *_arr;
size_t _capacity;
size_t _end;
};
#endif//AUTO_VECTOR_H
Program received signal SIGSEGV, Segmentation fault.
0x0806b85a in std::auto_ptr<__shedskin__::setentry<__shedskin__::tuple2<int, int>*> >::get (this=0x0)
at /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/memory:300
300 get() const throw() { return _M_ptr; }
(gdb) bt
#0 0x0806b85a in std::auto_ptr<__shedskin__::setentry<__shedskin__::tuple2<int, int>*> >::get (this=0x0)
at /usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/memory:300
#1 0x0806be61 in __shedskin__::set<__shedskin__::tuple2<int, int>*>::lookup (this=0x80a3c58, key=0x80a3c40,
hash=-1919631394) at ../Include/builtin.hpp:3223
#2 0x0806bfc7 in __shedskin__::set<__shedskin__::tuple2<int, int>*>::insert_key (this=0x80a3c58, key=0x80a3c40,
hash=-1919631394) at ../Include/builtin.hpp:3258
#3 0x080728ea in __shedskin__::set<__shedskin__::tuple2<int, int>*>::add (this=0x80a3c58, key=0x80a3c40)
at ../Include/builtin.hpp:3278
#4 0x0806af0c in main (Argc_=<value optimized out>, Argv_=<value optimized out>) at ../Source/mdMatchupTest.cpp:93
(gdb) frame 1
#1 0x0806be61 in __shedskin__::set<__shedskin__::tuple2<int, int>*>::lookup (this=0x80a3c58, key=0x80a3c40,
hash=-1919631394) at ../Include/builtin.hpp:3223
3223 setentry<T>* entry = table->operator[](i)->get(); // &table[i]发布于 2011-02-16 06:06:01
我有一种感觉,NFA和auto_vector的作者在这里搞错了。为什么成员是指针?您应该利用RAII;这正是C++优于其他语言的地方!您可以保证,当有效的自动对象超出作用域时,它的析构函数将被调用,而不管堆栈是由于异常而倒带还是干净地展开。充分利用这个保证吧!
首先,丢弃那个aut_vector类。你不需要它。使用std::vector<boost::shared_ptr<T> >。当然是作为自动成员,而不是指针成员。然后删除析构函数;您不需要它。
在这里,您删除了一个完整的类和一个析构函数。如果你有一个拷贝构造函数,你应该有一个赋值运算符,还有一个交换成员,这将是一个很好的想法,那么你也可以消除它们。这消除了大量的代码,并实现了大量的正确性。一举两得。
发布于 2011-02-18 11:39:25
I have solved the segmentation fault problem. It occured when memory allocated with malloc was deallocated with delete, thereby corrupting the heap. I replaced all the malloc's with the new operator. The reason the malloc was mismatched with delete was because the python to C++ converter program used the Boehm garbage collector. We are taking out the Boehm garbage collector and replacing it with new and delete. The Boehm garbage collector has two disadvantages, First, it pauses at random times during garbage collection. Second, it has a finite amount of heap memory which can only be changed at compile time. As a result, it has scalability issues with large applications.
The auto_vector class runs Okay. I tested it with Valgrind and there were no major problems. The memory leak has been addressed. Thank you for all the Boost suggestions. https://stackoverflow.com/questions/5009952
复制相似问题