-1

I am trying to test/debug a simple c++ code with template class and copy constructor. I define a vector class (user defined not STL) with 2 constructors one for initialization of vector elements and another for assigning values from an array. First I call the initialization constructor ,the code runs fine ,but when I call the constructor with a float array elements , the very first assignment statement hits SIGSEGV error , I have checked all values and addresses in debugger , no hints found. I give below the code ,I give below the sequence of calls and line details of error , from main vector() is called ,no issues , then v1=inputf1; is invoked ,then the copy constructor vector(T1* t2) is invoked , there code hits SIGSEGV error at very first assignment stmt in the loop that is t[i]=t2[i]; ,please help understand, since the code is small you can as well try executing and let me know -Thanks.

#include <stdio.h>
#include <iostream>

using namespace std;

const int size = 4;

template <class T1>

class vector {
    
    T1* t;
    
public:
    
    vector() {
        
        t = new T1[size];
        
        for(int i=0;i<size;i++)
            t[i] =0;
        
    }


    vector(T1* t2) {
                
        for(int i=0;i<size;i++)
            t[i]=t2[i];//SIGSEGV error at this stmt//
        
        }
    
        
    T1 operator * (vector &va) {
        
        T1 sum=0;
        
        for(int i=0;i<size;i++)
            sum += this->t[i]*va.t[i];
            
        return sum;
                
    }
    
};

int main(int argc, char **argv)
{
    
    int ip;
    float ipf;
    
    float inputf1[4] = {1.2,2.3,3.4,4.5};
    vector<float> v1;
    v1=inputf1;
    float inputf2[4] = {5.6,6.7,7.8,8.9};
    vector<float> v3;
    v3=inputf2;
    
    int inputi1[4] = {1,2,3,4};
    vector<int> v2;
    v2=inputi1;
    
    int inputi2[4] = {5,6,7,8};
    vector<int> v4;
    v4=inputi2;
    
    ip = v2*v4;
    ipf = v1*v3;
    
    cout<<"inner product of int vectors = "<< ip <<endl;
    
    cout<<"inner product of float vectors = "<< ipf <<endl;
    
     
        
    return 0;
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • 2
    `t` is not initialized in the `vector(T1* t2)` constructor prior to the assignment. Namig your class `vector` + `using namespace std` is a disaster waiting to happen. Same goes for `size` and `std::size`. – Quimby Jun 04 '22 at 11:35

1 Answers1

0

The issue is not initializing t in vector(T1 *t2).

In this case you could inherit the constructors like this:

vector(T1 *t2):vector() {

    for (int i = 0; i < size; i++)
        t[i] = t2[i]; 
}

But where is vector(T1 *t2) called? In each assignment because there is not operator taking T*.

v1=inputf1

is rewritten as

v1.operator=(vector<float>(inputf1));

because the compiler found this implicit conversion to work. Of course neither operator= nor vector(T* vals) are implemented correctly, so it will fail somewhere.

Even if you fix the constructor, your code has errors because you did not implement the rule of five correctly.

Notes

copy constructor vector(T1* t2)

This is not a copy constructor, but an ordinary one. vector(const vector<T1>&) would be the copy ctor.

Consider making constructor with one argument explicit, this would forbid the implicit conversion.

At least directly initialize each member as a backup if you forget. T* t=nullptr;, this will make the code deterministically segfault. Better than nothing.

I have checked all values and addresses in debugger , no hints found.

I find that dubious, what kind of debugger are you using? Because common ones will break on segfaults, give call stack, and allow inspecting of all variables. You would see t not being initialized there.

Your code is really unsafe, do not use using namespace std, you have clashes with std::size already and will have more if you #include <vector>. How does it compile for you? It does not for me.

I recommend to get a decent compiler, debugger, enable warnings -Wall -Wextra -Werror and use sanitizers, they are really quick for tracking errors. Address sanitizer shows for example:

==1==ERROR: AddressSanitizer: SEGV on unknown address 0x7fbd726014d0 (pc 0x000000401d0c bp 0x7ffe0c253230 sp 0x7ffe0c253210 T0)
==1==The signal is caused by a WRITE memory access.
    #0 0x401d0c in vector<float>::vector(float*) /app/example.cpp:28
    #1 0x401615 in main /app/example.cpp:57
    #2 0x7fbd726490b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x240b2)
    #3 0x40114d in _start (/app/output.s+0x40114d)

Thus making the error clear.

Quimby
  • 17,735
  • 4
  • 35
  • 55
  • Thanks Quimby , just adding this one line vector(T1 *t2):vector() helped and got the expected result ,btw I am using codelite IDE with MinGW which is a "decent" compiler for windows I believe. – Madavan Viswanathan Jun 04 '22 at 12:41