初始化对象时出现分段错误

Segmentation fault at initializing the object

本文关键字:分段 错误 对象 初始化      更新时间:2023-10-16
Class vector
{
    int *v ;
    int size;
    public:
    vector(int m ) // create a null vector
    {
        v=new int[size = m];
        for(int i=0;i<size;i++)
            v[i]=0;
    }
    vector(int *a) //create a vector from an array
    {
        for(int i=0;i<size;i++)
            v[i]=a[i];
    }
    int operator*(vector &y) //scalar product
    {
        int sum=0;
        for(int i=0;i<size;i++)
            sum+=this->v[i]*y-v[i];
        return sum;
    }
}; 

int main()
{
    int x[3]={1,2,3};
    int y[3]={4,5,6};
    vector v1(3); //create a null vector of 3 integers
    vector v2(3);
    v1=x; //create v1 from the array x
    v2=y;
    int R=v1*v2;
    cout<<”R=”r;
    return 0;
} 

执行上述程序后,我在这一点上遇到分段错误("v1=x;)任何人都可以解释为什么我遇到分段错误。

当您从int*构造vector时,您不会设置size,而是访问其值。此构造函数用于从赋值所需的int*vector的隐式转换。访问未初始化的值会导致程序具有未定义的行为。最有可能的是,size具有某些价值,可以有效地访问一些无法访问的内存。

您已将作业的左侧设置为具有特定大小这一事实无济于事。如果您将自己的分配从int*定义为vector,可能会有所帮助:

vector& vector= (int* other) {
     // ...
}

使用此赋值运算符(当然,使用合适的实现)将避免从 int*vector 的隐式转换,并且您可以使用左侧的size

到目前为止,这不是唯一包含您的代码的程序:

  • 您分配内存,但从不释放它。如果在构造函数中分配内存,则需要析构函数来释放内存。
  • 当然,一旦你这样做了,你可以轻松地多次释放内存,因为你没有复制构造函数或复制赋值,编译器生成的版本会做一个平面副本。

问题在于内存的分配方式。我们只看这四行:

vector v1(3); //create a null vector of 3 integers
v1=x; //create v1 from the array x

在第一行中,使用 vector(int m) 构造函数形式创建一个新对象 v1。这里在堆上分配了一个新的 int 数组。

在第三行中创建一个新对象,替换在第 1 行中分配的对象。问题从这里开始了,因为这行使用 vector(int *a) 构造函数,它既不分配 v 数组,也不设置 size 变量。因此,您将输入复制到导致堆栈错误的未分配地址。此外,永远不会释放在第一行的构造函数中分配的内存。

代码的其他问题:在 * 运算符中,您将 int 与向量相乘

sum += this->v[i] * y - v[i];
                  ^^^

尽管未定义此乘法运算符。

此行也不会编译:

cout<<”R=”r;

首先是因为"R="和r之间缺少<<,然后是因为奇怪的".