-1

This is embarrassing, but I'm a little rusty on my C++ and for the life of me I can't see why this code is causing a segmentation fault. The weird this is that several iterations ago it seemed to work fine. I don't even know what I'm doing differently now.

It's basically a constructor for a template class object that is meant to hold three of the objects. I am getting a seg fault on the first line of the constructor's implementation (where I assign a to x*):

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;
}

I've tried a few variations on this including

x* = a;

x = new(a);

And I've tried having the function work like so:

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

But then it wouldn't let me call it by using:

VecXd<int>(1,2,3);

Thank you very much for your time, it is much appreciated!

JDS
  • 1,173
  • 12
  • 26
SemperCallide
  • 1,950
  • 6
  • 26
  • 42
  • 2
    This code doesn't compile in the first place, so obviously it can't segfault either. Please show us the real code. – syam Sep 22 '13 at 16:56
  • `new` returns a pointer, and *x is asking for a value, for one thing. Can you just use `x = new T(a)`? – BrainSteel Sep 22 '13 at 16:57
  • Why are you trying to assign an object to a de-referenced pointer? – OldProgrammer Sep 22 '13 at 16:57
  • 3
    This isn't even *compilable*. `T * x, T * y, T * z;` is not a legal declaration. Post the *real* code please. And even if you fix that, `*x = new T(a);` dereferences whatever indeterminate value is in `x` (it is uninitalized) and attempts to store an allocation return address within it. – WhozCraig Sep 22 '13 at 16:57

1 Answers1

2

You are dereferencing your member variables before assignment. Directly assign the new pointers to them:

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

Of course, you are going to leak this memory unless you have a destructor as well.

Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
  • 1
    Thank you very much! I will post the full code next time. I naively thought I was being polite by trying to isolate the problem first; I didn't realize that that made it harder to solve. Thanks again. – SemperCallide Sep 22 '13 at 17:47