我有一段C ++测试代码在Rstudio中工作正常,它使用g ++,但会在MSVS 2012中导致运行时错误:
template<typename T>
struct vec{
T*head, *tail;
vec()
{
head=NULL;
tail=NULL;
}
vec(int n)
{
head=(T*)malloc(sizeof(T)*n);
tail=head+n;
}
T operator [] (int i) const {return *(head+i);}
T & operator [] (int i) {return *(head+i);}
~vec(){free(head);}
};
int main(){
std::vector<int>y(3);
y[0]=1; y[1]=2; y[2]=3;
vec<int>x1(3);
x1[0]=y[0];
std::cout<<"vec of integers, [] overloading works fine \n";
std::vector<std::vector<int>::iterator>z(3);
z[0]=y.begin();
z[1]=y.begin()+1;
z[2]=y.begin()+2;
vec<std::vector<int>::iterator>x2(3);
x2[0]=z[0];
std::cout<<*x2[0]<<"\n";
std::cout<<"vec of std::vector::iterator, [] overloading g++ works fine, MSVS doesn't \n";
return 1;
}
代码显示如果vec包含整数,MSVS和Rstudio都可以正常工作;如果vec包含迭代器,MSVS将遇到以下错误:
我感觉它与迭代器有关。有人能让我知道我的错误在哪里吗?顺便说一下,我只在MSVS中包含了矢量头文件。
谢谢!
答案 0 :(得分:2)
VS在调试模式下对其迭代器进行了额外的错误检查。它在您的代码中发现了一个合法的错误!错误是您将未初始化的内存重新解释为初始化对象:
vec(int n){head=(T*)malloc(sizeof(T)*n);tail=head+n;}
^^^^^^^^^^^^^^^^^^^^^^^
T & operator [] (int i) {return *(head+i);}
^^^^^^^^^
x2[0]=z[0];
^^^^^^
赋值在向量迭代器对象上调用operator=
,它实际上是未初始化的内存,当它尝试将某些内存解释为有效数据时,会导致崩溃。 (顺便说一句,0xCDCDCDCD是调试器通常填充未初始化的内存以帮助更快地捕获这些错误。)
我建议使用new
/ delete
而不是malloc。原始内存分配在C ++中是很难的(正常的内存管理已经非常难了)。
另请注意,在一般情况下,malloc
可能不会为所有对象类型生成具有足够高对齐的块(尽管大部分时间都是这样,因为很少有对象对齐超过16个字节)。
答案 1 :(得分:1)
您正在使用malloc
分配(未初始化的)内存并尝试将其解释为非POD类型,如迭代器可以。这必然会失败 - 对象的operator=
期望初始化对象作为其左操作数,但是你给它一个垃圾值(因此崩溃)。
另外,你没有打电话给你的元素&#39;析构函数,因为你使用普通free
。
一个简单的解决方案是在构造函数中使用new T[n]
而不是malloc
(以及析构函数中的delete[]
)。这要求您的T
可以默认构建;有办法削弱这个要求(涉及放置new
和一些技巧,以保证对齐)。
顺便说一句,你的vec
课程既没有实现三个&#34;规则,也没有实现三个&#34;规则。也没有&#34;规则的五个&#34;,既不会禁用复制结构,所以如果你的vec对象被复制,你将有双重释放。