【发布时间】:2011-10-13 11:20:42
【问题描述】:
我遇到了一个技术问题,这真的让我很困惑。我提前道歉,因为我可能没有提供相关细节;我还不知道为什么会出错,而且包含我正在使用的所有代码是过分的。
我正在处理一个使用 C++ STL 的大型程序。我正在将此代码移动到一个非常敏感的环境,没有标准的 clib 或 STL 实现;它将重新定义 malloc/free/new/delete 等...为此,我需要用我自己的简化实现替换 std:: 部分。我从 std::vector 开始。现在它在标准生态系统中运行,所以它是 GNU libc 和 STL。唯一改变的是这个向量类。
当我使用替换的类执行程序时,它会出现段错误。我已经通过 GDB 进行了处理,发现程序将使用下标运算符从向量中请求一个对象。当对象引用被返回时,一个方法被调用并且程序段错误。似乎找不到此方法并最终出现在 GDB 的 main_arena() 中。对象的类型是继承类。
我真的完全不确定这里有什么问题。我很想提供更多细节,但我不确定我还能提供什么。我只能假设我的向量实现有问题,因为程序中没有任何其他内容被更改。也许有一些明显的事情我在这里做错了,我根本没有看到。
我正在使用:g++ (GCC) 4.4.5 20110214 (Red Hat 4.4.5-6)
非常感谢任何反馈/建议!
#ifndef _MYSTL_VECTOR_H_
#define _MYSTL_VECTOR_H_
#include <stdlib.h>
#include <assert.h>
typedef unsigned int uint;
namespace mystl
{
/******************
VECTOR
********************/
template <typename T>
class vector
{
private:
uint _size;
uint _reserved;
T *storage;
void init_vector(uint reserve)
{
if (reserve == 0)
{
_reserved = 0;
return;
}
storage = (T*)malloc(sizeof(T)*reserve);
assert(storage);
_reserved = reserve;
}
public:
vector()
{
// std::cerr << "default constructor " << this << std::endl;
storage = NULL;
_size = 0;
_reserved = 0;
}
vector(const vector<T> &other)
{
// std::cerr << "copy constructor " << this << std::endl;
storage = NULL;
_size = 0;
_reserved = 0;
init_vector(other.size());
_size = other.size();
for (uint i=0; i<other.size(); i++)
{
storage[i] = T(other[i]);
}
}
vector(uint init_num, const T& init_value)
{
// std::cerr << "special constructor1 " << this << std::endl;
storage = NULL;
_size = 0;
_reserved = 0;
init_vector(init_num);
for (size_t i=0; i<init_num; i++)
{
push_back(init_value);
}
}
vector(uint init_num)
{
// std::cerr << "special constructor2 " << this << std::endl;
storage = NULL;
_size = 0;
_reserved = 0;
init_vector(init_num);
}
void reserve(uint new_size)
{
if (new_size > _reserved)
{
storage = (T*)realloc(storage, sizeof(T)*new_size);
assert(storage);
_reserved = new_size;
}
}
void push_back(const T &item)
{
if (_size >= _reserved)
{
if (_reserved == 0) _reserved=1;
reserve(_reserved*2);
}
storage[_size] = T(item);
_size++;
}
uint size() const
{
return _size;
}
~vector()
{
if (_reserved)
{
free(storage);
storage = NULL;
_reserved = 0;
_size = 0;
}
}
// this is for read only
const T& operator[] (unsigned i) const
{
// do bounds check...
if (i >= _size || i < 0)
{
assert(false);
}
return storage[i];
}
T& operator[] (unsigned i)
{
// do bounds check...
if (i >= _size || i < 0)
{
assert(false);
}
return storage[i];
}
// overload = operator
const vector<T>& operator= (const vector<T>& x)
{
// check for self
if (this != &x)
{
_reserved = 0;
_size = 0;
storage = NULL;
init_vector( x.size() );
for(uint i=0; i<x.size(); i++)
{
storage[i] = T(x[i]);
}
_size = x.size();
}
return *this;
}
uint begin() const
{
return 0;
}
void insert(uint pos, const T& value)
{
push_back(value);
if (size() == 1)
{
return;
}
for (size_t i=size()-2; i>=pos&& i>=0 ; i--)
{
storage[i+1] = storage[i];
}
storage[pos] = value;
}
void erase(uint erase_index)
{
if (erase_index >= _size)
{
return;
}
//scoot everyone down by one
for (uint i=erase_index; i<_size; i++)
{
storage[i] = storage[i+1];
}
_size--;
}
void erase(uint start, uint end)
{
if (start > end)
{
assert(false);
}
if (end > _size)
end = _size;
for (uint i=start; i<end; i++)
{
erase(start);
}
assert(false);
}
void clear()
{
erase(0,_size);
}
bool empty() const
{
return _size == 0;
}
}; //class vector
}
#endif // _MYSTL_VECTOR_H_
【问题讨论】:
-
你能给我们一个简单的
main()来复制段错误吗? -
这看起来躲不过
if (i >= _size || i < 0),unsigned i怎么会小于0? -
不幸的是,我无法用最小化的代码复制故障。我想在我创建对象、将它们存储在向量中并再次访问它们之间发生了一些事情。我再玩一会儿。
标签: c++ stl vector g++ segmentation-fault