如何使用 std::vector<unsigned char*> 成员变量为类编写复制构造函数
How to write a copy constructor for a class with std::vector<unsigned char*> member variable
成员向量的简单赋值是否足够?
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;
};
我的析构函数出现了一个漏洞,这让我怀疑复制构造函数可能是罪魁祸首。也可能是我的问题在别处
编辑
增加缓冲区的长度。这不是完整的类定义,我只是想提供足够的信息来寻求帮助。不,我不能使用std:: string因为我想与c函数共享成员向量可以写入缓冲区
由于不存储分配的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++;
}
}
你真的比使用我最初的建议要好得多。更不容易出错
你的vector包含指向堆内存的指针。假设你做widgetNamesA=widgetNamesB
,其中一个超出了作用域。析构函数被调用,内存被删除。由于另一个对象指向相同的地址,它现在指向垃圾,任何访问都将导致崩溃。
您最好像其他答案建议的那样使用std::string()。
EDIT:如果不能使用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
。
那么标准库vector确实可以通过简单赋值复制。不幸的是,unsigned char*
不是,矢量不知道这一点。因为你是手动处理指针的构造和销毁,这意味着你也必须手动处理复制。
更好的做法是使用std::string(或者std::basic_string)的vector,这样构造/复制/移动/销毁都是自动处理的。
相关文章:
- 没有用于初始化C++中的变量模板的匹配构造函数
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 在类构造函数中使用结构变量
- 在 c++ 中将变量作为结构构造函数中的引用传递
- 在类构造函数中定义结构变量的参数
- 修改程序的入口点时未调用全局变量的构造函数
- C++:将向量传递到构造函数以创建成员变量的最佳方法?
- 为什么从另一个构造函数内部调用C++构造函数不修改类变量?
- 在 C++ 中声明 const 对象需要用户定义的默认构造函数.如果我有一个可变成员变量,为什么不呢?
- 构造函数干扰成员变量指定的初始值设定项?
- 类中的数组变量C++导致"was not declared in this scope"实现文件的一个函数中错误,但在构造函数中不会导致错误
- 通过 C++ 中的重载构造函数初始化未知类型的变量
- 如何在初始化列表中的构造函数之后初始化变量/对象?
- 我可以使用在类构造函数中初始化的流类型的成员变量吗?
- 为什么 std::move 不将默认移动构造函数中的源变量更改为默认值?
- C++为具有引用成员变量的类创建复制构造函数
- 带有常量构造函数参数的C++变量构造函数方法
- 全局变量构造函数/析构函数是否需要线程保护
- G++ 4.6 -std=gnu++0x:静态局部变量构造函数调用计时和线程安全
- 来自静态变量构造函数/析构函数的异常