EXC_BAD_ACCESS C++ 数组反向器中的错误
EXC_BAD_ACCESS error in C++ array reverser
下面是一个简单的程序,用于创建一个与传递的数组相反的数组。该代码在第 6 行抛出以下错误:Thread 1: EXC_BAD_ACCESS (code=1, address=0x7fff0000002c)
。程序编译成功,逻辑似乎没问题。有人可以解释我的错误吗?
void arrayReverser(int array[], int arrayLength) {
int arrayNew[arrayLength];
int current;
current = array[0];
for(int i = 0; current != '[=11=]'; current = array[++i]) {
arrayNew[i] = array[arrayLength - i]; // Thread 1 error code occurs here
}
array = arrayNew;
}
int main() {
int array[] = { 2, 3, 4, 5, 6, 7 };
arrayReverser(array, 6);
}
看来你有两个问题。首先,您的数组反向器逻辑用于基于数组中不存在的终止符进行循环。您应该改为基于数组长度进行循环。
其次,您的 arrayReverser 函数正在堆栈上分配 return 值 (arrayNew)。堆栈分配的局部变量在方法结束时自动释放。您需要使用 new 或 malloc 将堆上的 return 值分配给 return - 并在 main.delete/free 中使用 delete/free 释放它。
如果您希望保持 main 中的数组完好无损,而不是使用动态分配,您可以将值分配到位,如下所示:
#include <iostream>
void arrayReverser(int array[], int arrayLength) {
int arrayNew[arrayLength];
// Reverse the array using array length as terminator
for( int i=0; i <= arrayLength; i++ ) {
arrayNew[arrayLength-i] = array[i-1];
}
// Assign elements back to original array, instead of assigning array pointer
for( int i=0; i < arrayLength; i++ ) {
array[i] = arrayNew[i];
}
}
int main() {
int array[] = { 2, 3, 4, 5, 6, 7 };
arrayReverser(array, 6);
// Output reveresed array
for( int i=0; i < 6; i++ ) {
std::cout << array[i] << std::endl;
}
}
这是可行的,因为它重新使用发送的数组作为结果 - 并且您的 "arrayNew" 变量可以在不使用的情况下安全地销毁。 "deep copy" 的数组元素保留了原始数组的分配。
您的问题是 for 循环中的检查:
当前 != '\0'
这应该是对数组长度的检查,而不是数组中元素的值,不过这可以反转以空字符结尾的字符串。
查看这一行的循环继续条件:
for(int i = 0; current != '[=10=]'; current = array[++i]) {
您一直循环直到遇到 NUL ('\0') 字符(它的整数值为 0)。
您传入的数组末尾没有零 'sentinel'。
看起来你打算使用 arraylength
参数然后有一个 'brain fart'.
代码刚跑完数组的末尾,然后在某处执行非法访问。
PS:数组长度参数请使用size_t
。这就是它的用途。
下面是一个简单的程序,用于创建一个与传递的数组相反的数组。该代码在第 6 行抛出以下错误:Thread 1: EXC_BAD_ACCESS (code=1, address=0x7fff0000002c)
。程序编译成功,逻辑似乎没问题。有人可以解释我的错误吗?
void arrayReverser(int array[], int arrayLength) {
int arrayNew[arrayLength];
int current;
current = array[0];
for(int i = 0; current != '[=11=]'; current = array[++i]) {
arrayNew[i] = array[arrayLength - i]; // Thread 1 error code occurs here
}
array = arrayNew;
}
int main() {
int array[] = { 2, 3, 4, 5, 6, 7 };
arrayReverser(array, 6);
}
看来你有两个问题。首先,您的数组反向器逻辑用于基于数组中不存在的终止符进行循环。您应该改为基于数组长度进行循环。
其次,您的 arrayReverser 函数正在堆栈上分配 return 值 (arrayNew)。堆栈分配的局部变量在方法结束时自动释放。您需要使用 new 或 malloc 将堆上的 return 值分配给 return - 并在 main.delete/free 中使用 delete/free 释放它。
如果您希望保持 main 中的数组完好无损,而不是使用动态分配,您可以将值分配到位,如下所示:
#include <iostream>
void arrayReverser(int array[], int arrayLength) {
int arrayNew[arrayLength];
// Reverse the array using array length as terminator
for( int i=0; i <= arrayLength; i++ ) {
arrayNew[arrayLength-i] = array[i-1];
}
// Assign elements back to original array, instead of assigning array pointer
for( int i=0; i < arrayLength; i++ ) {
array[i] = arrayNew[i];
}
}
int main() {
int array[] = { 2, 3, 4, 5, 6, 7 };
arrayReverser(array, 6);
// Output reveresed array
for( int i=0; i < 6; i++ ) {
std::cout << array[i] << std::endl;
}
}
这是可行的,因为它重新使用发送的数组作为结果 - 并且您的 "arrayNew" 变量可以在不使用的情况下安全地销毁。 "deep copy" 的数组元素保留了原始数组的分配。
您的问题是 for 循环中的检查:
当前 != '\0'
这应该是对数组长度的检查,而不是数组中元素的值,不过这可以反转以空字符结尾的字符串。
查看这一行的循环继续条件:
for(int i = 0; current != '[=10=]'; current = array[++i]) {
您一直循环直到遇到 NUL ('\0') 字符(它的整数值为 0)。
您传入的数组末尾没有零 'sentinel'。
看起来你打算使用 arraylength
参数然后有一个 'brain fart'.
代码刚跑完数组的末尾,然后在某处执行非法访问。
PS:数组长度参数请使用size_t
。这就是它的用途。