尝试在void函数中更改指针时引发异常

时间:2020-09-07 00:36:51

标签: c++ function pointers reference void

我正在尝试制作一个void函数,该函数会更改我传递的指针。代码在其中一行上引发了异常,我不确定为什么。难道我无法将数组作为指针传递然后在其上实现数学运算吗?我以为我已经重新分配了修复它的指针,但这似乎不起作用。

无效函数:

#include <iostream>
using namespace std;

void* func2(int one, double *value1[], int two, double *value2[], double  *final1) {
    double testval;
    double finalval = 0;
    //double *final1;
    double final = 0;
    for (int i = 1; i < one; i++) {
        for (int j = 1; j < two; j++) {
            testval = *value1[i] * *value2[j]; //exception thrown (works up to this point)
            finalval = testval + finalval;
        }
        final = finalval + final;
    }
    *final1 = final;
    return 0;
}

主要功能:

int main(){
    double *array1 = new double[input1];
    double *array2 = new double[input2];
//for loop that takes user input and fills in array1 and array2 with size and a list of values
...
double testval2;
func2(input1, &array1, input2, &array2, &testval2);
cout << testval2 << endl;

delete[] array1;
delete[] array2;
return 0;

我对指针还比较陌生,所以如果代码有点不懂,我深表歉意。

1 个答案:

答案 0 :(得分:1)

您似乎想将两个1D数组传递给func2()

一种实现方法是从函数签名中将[]删除为

(int one, double *value1, int two, double *value2, double *final1)

在函数中,将*value1[i]更改为value1[i],并类似地将value2更改为。从main()调用函数时,请删除&

其他一些想法:

  • 我不确定如何从您的代码中引发异常。但是*value1[i]绝对是无效的内存访问,因此您可能会看到一条segmentation fault消息。解决这些错误的有用工具是AddressSanitizer,可以通过使用-fsanitize=address进行编译在clang或gcc中启用,或者如果使用的是Xcode,则有an option for it。另一个很棒的工具是valgrind

  • 手动分配动态数组是使用C ++的一种类似于C的方式。在C ++中,将数组创建为std::vector对象是惯用的,它在幕后以相同的方式工作(它也分配动态数组),但是具有更方便的接口。特别是,向量会自动清理自身,因此无需调用delete[],并且向量知道其自身大小,因此无需像动态数组那样将大小作为单独的参数传递。

编辑:这是一条注释,用于说明为什么原始代码设法编译但在运行时失败。

在函数签名中,*上的[]double *value1[]的组合使value1成为指向double的指针,相当于double **value1 。在main()中,array1是double *。调用函数时,&array1使用该double *的地址,从而获得double **。因此,类型匹配并且代码可以编译。

代码在*value1[i]上的运行时失败。 value1是一个指向double的指针,内部指针指向动态数组。因此,本来打算(*value1)[i]首先解除外部指针的引用,然后再下标到动态数组中。但是,在C ++中,下标(a[])的操作符优先于解引用(*a)的操作,因此,其后向读取为*(value1[i])。为外部指针value1[i]下标对非零i无效,它从堆栈中的某个位置读取内存并将其任意解释为double *。然后,周围的*( )尝试取消引用此中断的指针。机器的内存保护抓住了这一点,操作系统发送了“ SIGSEGV”信号或类似程序将其杀死。