C++ 初始化带有本地对象的向量时出错
我想用不同类型的对象创建一个向量,但是 此代码引发以下异常: free():无效指针:0x0000000000401757***C++ 初始化带有本地对象的向量时出错,c++,pointers,vector,c++11,C++,Pointers,Vector,C++11,我想用不同类型的对象创建一个向量,但是 此代码引发以下异常: free():无效指针:0x0000000000401757*** #include <vector> class A { char * elem; public: A() { elem = new char[10]; } void setA(char* name) { elem = name; } ~A() {
#include <vector>
class A
{
char * elem;
public:
A()
{
elem = new char[10];
}
void setA(char* name)
{
elem = name;
}
~A()
{
delete[] elem;
}
};
int main(int argc, char **argv)
{
std::vector<A> v_a;
for (int i = 0; i < 10; ++i)
{
A m_a;
m_a.setA("jaja");
v_a.push_back(m_a);
}
}
#包括
甲级
{
char*elem;
公众:
()
{
elem=新字符[10];
}
无效setA(字符*名称)
{
elem=名称;
}
~A()
{
删除[]项;
}
};
int main(int argc,字符**argv)
{
std::向量v_a;
对于(int i=0;i<10;++i)
{
A m_A;
m_a.setA(“jaja”);
v_a.推回(m_a);
}
}
为什么会发生这种情况??如何实现正确的解决方案?您可以修改
elem
的值,该值是指向空闲存储区上分配的内存区域的指针。现在,elem
指向一个字符串文本,它不适用于delete
或delete[]
delete
ing不在免费存储中的对象是未定义的行为。尽管如此,析构函数仍会尝试执行此操作。调用setA(…)
时,您没有复制字符串的数据,而是复制本地字符串的地址。(检查有关指针和字符串文字的说明)
在使用setA(…)
调用的块结束后,此字符串超出范围,因此其地址在之后无效
因此,您正在尝试从堆栈上分配的析构函数的堆中释放内存,而此时该析构函数早已不存在了
更新建议1:于2016年1月27日添加
- 另外,在将
的实例推送到a
时,还需要考虑复制ctor。遵照命令,我还添加了一个复制赋值操作符 如遇以下情况,请参见std::vector
- 正确处理可能“错误”大小的字符串
#include <cstring> ... /// copy ctor A(const A& other) : elem(new char[10]) { // prevent duplicate code setA(other.elem); } /// copy assignment operator A& operator=(const A& other) { // prevent duplicate code setA(other.elem); return *this; } /// set A's name (which is truncated to 9 characters if necessary) void setA(const char* name) { // copy first 9 chars from name // if there's fewer chars: elem is padded with zeros std::strncpy(elem, name, 9); // add null character / zero (string delimiter) manually // this is necessary for cases where name has 10 or more chars elem[9] = 0; }
<强>建议2:切换到C++风格字符串
- 使用
(我更喜欢这个版本,因为它省去了内存处理,而且读取起来非常直观)std::string
#包括 甲级 { 字符串元素; 公众: A(){} void setA(std::string name) { elem=名称; } ~A(){} };
#include <cstring>
...
void setA(char* name, size_t length)
{
std::memcpy(elem, name, length);
}
#include <string>
class A
{
std::string elem;
public:
A(){}
void setA(std::string name)
{
elem = name;
}
~A(){}
};