定制的容器与g ++(Rstudio)一起使用,与MSVS 2012不一样

时间:2016-03-19 03:35:51

标签: c++ visual-studio rstudio

我有一段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将遇到以下错误:

enter image description here

我感觉它与迭代器有关。有人能让我知道我的错误在哪里吗?顺便说一下,我只在MSVS中包含了矢量头文件。

谢谢!

2 个答案:

答案 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对象被复制,你将有双重释放。