调用返回指针的函数时出现分段错误

Segmentation fault when calling a function returning a pointer

本文关键字:分段 错误 函数 返回 指针 调用      更新时间:2023-10-16

在调用返回c++指针的函数时,我得到了一个段错误。这里的问题是什么?这个函数似乎在做它应该做的事情,但是当它要返回的时候,它就遇到了问题。

#include<iostream>
double * v_scalar_prod(double a, double *b, int n)
{
    double *res ;
    int i;
    for (i = 0; i < n; i++) {
        *(res+i) = a*b[i];
        std::cout << std::setprecision(10) << "res = " << *(res+i) << 'n';
    }
    return res;
}

int main()
{

    double y[3] = {3., 5.45, 2.};
    double *z = new double[3];
    z = v_scalar_prod(4., y, 3);
}
输出:

$ ./program
res = 12
res = 21.8
res = 8
Segmentation fault (core dumped)

您为z分配内存,但您没有将其传递给函数。此外,您试图在函数中填充的数组没有为其分配内存。因此,即使没有段错误,您返回的指针也会指向某个随机地址。将其更改为以下内容(这是一种可能的修复方法):

#include<iostream>
double * v_scalar_prod(double a, double *b, int n)
{
    double *res  = new double[3];
    int i;
    for (i = 0; i < n; i++) {
        *(res+i) = a*b[i];
        std::cout  << "res = " << *(res+i) << 'n';
    }
    return res;
}
int main()
{
    double y[3] = {3., 5.45, 2.};
    double *z ;
    z = v_scalar_prod(4., y, 3);
    delete [] z;
}

让我们使用std::vector:

#include <iostream>
#include <vector>
#include <iomanip>
typedef std::vector<double> DoubleArray;
DoubleArray v_scalar_prod(double a, double *b, int n)
{
   DoubleArray res(n);
   for (int i = 0; i < n; i++) 
   {
        res[i] = a*b[i];
        std::cout << std::setprecision(10) << "res = " << res[i] << 'n';
   }
   return res;
}
int main()
{
   double y[3] = {3., 5.45, 2.};
   DoubleArray z = v_scalar_prod(4., y, 3);
}

没有内存泄漏,如果delete[]被调用,没有跟踪,等等。此外,这个版本可以在更大、更复杂的程序中使用,而不必担心内存泄漏。

唯一需要仔细检查的是v_scalar_prod函数中的b在循环之前和循环期间是否指向有效内存。你也可以让b成为一个DoubleArray,并通过const引用传递它。然后您可以执行以下操作:

DoubleArray v_scalar_prod(double a, const DoubleArray& b)
{
   DoubleArray res(b.size());
   for (int i = 0; i < b.size(); i++) 
   {
        res[i] = a*b[i];
        std::cout << std::setprecision(10) << "res = " << res[i] << 'n';
   }
   return res;
}

现在不需要n参数,因为vector通过调用vector::size()知道它的大小。

尝试初始化数组

double* res = new double[n];

或者任何你喜欢的变化

这样当你对这里的点进行引用时:

*(res+i) = a*b[i];

可以使用赋值操作符将该空格处的值赋给所计算的值。