为啥这个非常简单的构造函数会导致段错误?

Posted

技术标签:

【中文标题】为啥这个非常简单的构造函数会导致段错误?【英文标题】:Why is this very simple constructor causing a seg fault?为什么这个非常简单的构造函数会导致段错误? 【发布时间】:2013-09-22 16:53:34 【问题描述】:

这很尴尬,但我对我的 C++ 有点生疏,而且在我的一生中,我不明白为什么这段代码会导致分段错误。奇怪的是,几次迭代前它似乎工作正常。我什至不知道我现在在做什么不同。

它基本上是一个模板类对象的构造函数,用于保存三个对象。我在构造函数实现的第一行(我将 a 分配给 x*)遇到 seg 错误:

VecXd.hpp:

#ifndef JF_VecXd
#define JF_VecXd

#include <iostream>

template <class T>
class VecXd
    public: 
        VecXd(T a, T b, T c);   

        VecXd(const VecXd & vector);

        T getElement(int n)const;
        void setElements(T a, T b, T c);
        void display();
        void VecXd<T>::clearElements();
        VecXd<T>& VecXd<T>::operator=(const VecXd& vector);

/*
        VecXd& VecXd::operator<<(const VecXd & vector);
        VecXd& VecXd::operator>>(const VecXd & vector);
        VecXd&  VecXd::operator+(const VecXd & vector);
        VecXd& VecXd::operator+=(const VecXd & vector);

        ~VecXd();
*/              

        private:
            T * x, T * y, T * z; 

;

template <class T> 
VecXd<T>::VecXd(T a, T b, T c)
    x = new T(a); 
    y = new T(b);
    z = new T(c);

//CVector& CVector::operator= (const CVector& param)


template <class T> 
VecXd<T>::VecXd(const VecXd & vector)
    x = new T(vector.getElement(0));
    y = new T(vector.getElement(1));
    z = new T(vector.getElement(2));


template <class T> 
VecXd<T>& VecXd<T>::operator=(const VecXd& vector)
    if(this != &vector)
        *x = vector.getElement(0);
        *y = vector.getElement(1);
        *z = vector.getElement(2);
    
    return *this;


template <class T> 
T VecXd<T>::getElement(int n) const
    n = n%3;
    T result;  
    switch(n)
        case 0: 
            result = *x;
            break;
        case 1:
            result = *y;
            break;
        case 2:
            result = *z;
            break;  
        
    return result;    


template <class T> 
void VecXd<T>::clearElements()
    delete x; 
    delete y;
    delete z;    


template <class T>
void VecXd<T>::setElements(T a, T b, T c)
    clearElements(); 
    *x = a;
    *y = b;
    *z = c;    


template <class T>
void VecXd<T>::display()
    std::cout << "x: " << x << "\n";
    std::cout << "y: " << y << "\n";
    std::cout << "z: " << z << "\n\n\n";


#endif

test.cpp:

#include "vecxd.hpp"
#include <iostream>

int main()
    std::cout << "Creating vector 1..." << std::endl;
    VecXd<int> v1(1,2,3);
    std::cout << "Vector 1:" << std::endl; 
    v1.display();

    std::cout << "Vector 2 (copy-constructed from v1):" << std::endl;
    VecXd<int> v2(v1);
    v2.display();

    std::cout << "V1 set to 3,4,5:" << std::endl;
    v1.setElements(3,4,5);
    v1.display();

    std::cout << "V2 = V1, display V2" << std::endl;
 //   v2 = v1; 
    v2.display();


    system("pause");

    return 0;

我已经尝试了一些变化,包括

x* = a;

x = new(a);

我已经尝试过让函数像这样工作:

VecXd(T &amp; a, T &amp; b, T &amp; c);

但是它不会让我通过使用来调用它:

VecXd&lt;int&gt;(1,2,3);

非常感谢您的宝贵时间,非常感谢!

【问题讨论】:

这段代码一开始就不能编译,所以显然它也不能出现段错误。请向我们展示真实代码。 new 返回一个指针,而 *x 要求一个值,一方面。你能用x = new T(a)吗? 您为什么要尝试将对象分配给取消引用的指针? 这甚至不是可编译的T * x, T * y, T * z; 不是法律声明。请发布 real 代码。即使您解决了这个问题,*x = new T(a); 也会取消引用 x 中的任何不确定值(它未初始化)并尝试在其中存储分配返回地址。 【参考方案1】:

您在分配之前取消引用您的成员变量。直接将新指针分配给它们:

template <class T> 
VecXd<T>::VecXd(T a, T b, T c)
    x = new T(a); 
    y = new T(b);
    z = new T(c);

当然,除非你也有析构函数,否则你会泄漏这块内存。

【讨论】:

非常感谢!下次我会发布完整的代码。我天真地认为我首先试图隔离问题是出于礼貌;我没有意识到这使得解决问题变得更加困难。再次感谢。

以上是关于为啥这个非常简单的构造函数会导致段错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥定义复制构造函数会给我错误:不能将'obj&'类型的非常量左值引用绑定到'obj'类型的右值?

为啥在构造函数中抛出异常会导致空引用?

为啥在构造函数中释放会导致 EXC_BAD_ACCESS?

为啥在尝试调用采用动态参数的基本构造函数/方法时会出现此编译错误?

为啥使用不同的 ArrayList 构造函数会导致内部数组的增长率不同?

为啥 C++ 构造函数在继承中需要默认参数?