成员向量的简单分配是否足够?
class WidgetNames
{
WidgetNames(int sz)
{
unsigned char* c = new unsigned char[ sz ];
memset(c,0,sz);
m_names.push_back( c );
m_len.push_back(sz);
}
~WidgetNames()
{
for ( size_t i = 0 ; i < m_names.size() ; ++i )
{
if( m_names[i] != NULL )
{
delete [] m_names[i];
}
}
}
WidgetNames(const WidgetNames &other)
{
m_names = other.m_names;
}
std::vector<unsigned char*> m_names;
std::vector<int> m_len;
};
我在析构函数中遇到了一个问题,这让我怀疑复制构造函数可能是罪魁祸首。或者可能是我的问题在其他地方
编辑
添加缓冲区的长度。这不是完整的类def我只是想提供足够的信息来征求帮助
不,我不能使用std :: string,因为我想与可以写入缓冲区的c函数共享成员向量
答案 0 :(得分:5)
由于你没有存储你分配的char数组的大小,所以没有办法做复制构造函数
尝试使用:
std::vector< std::vector< unsigned char > > m_names;
您的构造函数将如下所示。
WidgetNames(int sz)
{
std::vector< unsigned char > c;
c.resize( sz );
m_names.push_back( c );
}
代替。或者,更简单,因为它看起来像你正在存储的字符串只需使用
std::vector< std::string > m_names;
修改:上述情况无论你需要在复制构造函数中执行以下操作。
WidgetNames(const WidgetNames &other)
{
int i = 0;
while( i < m_names.size() )
{
delete[] m_names[i];
i++;
}
m_names.resize( other.m_names.size() );
m_len.resize( other.m_len.size() );
i = 0;
while( i < m_names.size() )
{
m_len[i] = other.m_len[i];
m_names[i] = new unsigned char[m_len[i]] );
memcpy( m_names[i], other.m_names[i], m_len[i] );
i++;
}
}
尽管如此,你真的可以更好地使用我的一个原始建议。更不容易出错。
答案 1 :(得分:2)
您的向量包含指向堆内存的指针。假设您执行widgetNamesA=widgetNamesB
,其中一个超出范围。调用析构函数,并删除内存。由于另一个对象指向相同的地址,它现在指向垃圾,任何访问都会导致崩溃。
与其他答案建议一样,你最好使用std :: string()。
编辑:如果你不能使用std :: string,那么就这样做:
WidgetNames(const WidgetNames &other){
//Release owned memory
for(int i=0; i<m_names.size(); i++ ){
delete m_names[i];
}
m_names.clear();
//Allocate new memory and copy right side's contents
for(int i=0; i<other.m_names.size(); i++ ){
m_names.push_back( new unsigned char[other.m_len[i]] );
memcpy( m_names[i], other.m_names[i], other.m_len[i] );
}
}
如果您使用智能指针(例如std::tr1::shared_ptr
),则可以忘记delete
。
答案 2 :(得分:0)
然后,通过简单的赋值,标准库矢量确实可以复制。不幸的是,unsigned char*
不是,而矢量不知道。由于您手动处理指针构造和销毁,这意味着您也必须手动处理副本。
更好的做法是使用std :: string(或者std :: basic_string)的向量,以便自动处理构造/复制/移动/销毁。