尝试更改 void 函数中的指针时抛出异常
Exception thrown when trying to change a pointer in a void function
我正在尝试创建一个 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;
我对指针比较陌生,如果代码有点文盲,我深表歉意。
您似乎想将两个一维数组传递给 func2()
。
一种方法是从函数签名中删除 []
作为
(int one, double *value1, int two, double *value2, double *final1)
在函数内,将 *value1[i]
更改为 value1[i]
,value2
也类似。并在从 main().
调用函数时删除 &
其他一些想法:
我不确定如何从您的代码中抛出异常。但是 *value1[i]
肯定是一个无效的内存访问,所以你可能看到的是一个 segmentation fault message. A helpful tool to troubleshoot these kinds of errors is AddressSanitizer, enabled in clang or gcc by compiling with -fsanitize=address
, or if you are using Xcode, there is an option for it. Another great tool is valgrind.
手动分配动态数组是使用 C++ 的一种很好的 C-like 方式。在 C++ 中,惯用的做法是将数组创建为 std::vector
对象,其底层工作方式相同(它也分配一个动态数组)但具有更方便的接口。特别是 vector 会自动清理自己,所以不需要调用 delete[]
,并且 vector 知道自己的大小,所以不需要像动态数组那样将大小作为单独的参数传递。
编辑:这里有一个注释来澄清为什么原始代码设法编译但在运行时失败。
在函数签名中,*
和 []
在 double *value1[]
上的组合使 value1
指向指向 double 的指针,相当于 double **value1
.在 main() 中,array1
是一个 double*。调用函数时,&array1
取那个double*的地址,得到一个double**。所以类型匹配,代码编译。
代码在 *value1[i]
的运行时失败。 value1 是指向双精度指针的指针,其中内部指针指向动态数组。所以我们的目的是 (*value1)[i]
首先取消引用外部指针,然后下标到动态数组中。但是,在 C++ 中,下标 (a[]
) 的运算符优先于取消引用 (*a
),因此它以倒序读取为 *(value1[i])
。下标外部指针value1[i]
对于非零i
无效,从栈中的某处读取内存并任意解释为double*。然后周围的 *( )
尝试取消引用这个破坏的指针。机器的内存保护捕捉到了这一点,OS 发送一个“SIGSEGV”信号或类似的程序来杀死它。
我正在尝试创建一个 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;
我对指针比较陌生,如果代码有点文盲,我深表歉意。
您似乎想将两个一维数组传递给 func2()
。
一种方法是从函数签名中删除 []
作为
(int one, double *value1, int two, double *value2, double *final1)
在函数内,将 *value1[i]
更改为 value1[i]
,value2
也类似。并在从 main().
&
其他一些想法:
我不确定如何从您的代码中抛出异常。但是
*value1[i]
肯定是一个无效的内存访问,所以你可能看到的是一个 segmentation fault message. A helpful tool to troubleshoot these kinds of errors is AddressSanitizer, enabled in clang or gcc by compiling with-fsanitize=address
, or if you are using Xcode, there is an option for it. Another great tool is valgrind.手动分配动态数组是使用 C++ 的一种很好的 C-like 方式。在 C++ 中,惯用的做法是将数组创建为
std::vector
对象,其底层工作方式相同(它也分配一个动态数组)但具有更方便的接口。特别是 vector 会自动清理自己,所以不需要调用delete[]
,并且 vector 知道自己的大小,所以不需要像动态数组那样将大小作为单独的参数传递。
编辑:这里有一个注释来澄清为什么原始代码设法编译但在运行时失败。
在函数签名中,*
和 []
在 double *value1[]
上的组合使 value1
指向指向 double 的指针,相当于 double **value1
.在 main() 中,array1
是一个 double*。调用函数时,&array1
取那个double*的地址,得到一个double**。所以类型匹配,代码编译。
代码在 *value1[i]
的运行时失败。 value1 是指向双精度指针的指针,其中内部指针指向动态数组。所以我们的目的是 (*value1)[i]
首先取消引用外部指针,然后下标到动态数组中。但是,在 C++ 中,下标 (a[]
) 的运算符优先于取消引用 (*a
),因此它以倒序读取为 *(value1[i])
。下标外部指针value1[i]
对于非零i
无效,从栈中的某处读取内存并任意解释为double*。然后周围的 *( )
尝试取消引用这个破坏的指针。机器的内存保护捕捉到了这一点,OS 发送一个“SIGSEGV”信号或类似的程序来杀死它。