如何删除我的 C++ 代码中的分段错误?
Posted
技术标签:
【中文标题】如何删除我的 C++ 代码中的分段错误?【英文标题】:How to remove Segmentation Fault in My C++ code? 【发布时间】:2021-09-12 17:20:12 【问题描述】:我编写了一个 C++ 函数,它以数组及其大小作为参数并执行某些操作。当我尝试运行此代码时,它显示分段错误。有人可以告诉我为什么此代码显示分段错误以及如何删除它?
void rearrange(long long *arr, int n)
long long temp[n];
int max = n-1;
int min = 0;
for(int i=0;i<n;i++)
if(i%2 == 0)
temp[i] = arr[max];
max--;
else
temp[i] = arr[min];
min++;
for(int i=0;i<n;i++)
arr[i] = temp[i];
【问题讨论】:
你是怎么调用这个函数的? 您尝试调试代码吗?long long temp[n];
不是有效的 c++。
您是否尝试编译代码,long long temp[n] 应该会报错。查看具有运行时确定大小的数组的 std::vector 。好消息是您可以通过显式引用传递它们,例如重新排列(std::vector我试图这样调用你的函数(不改变任何内容):
void rearrange(long long *arr, int n)
long long temp[n];
int max = n - 1;
int min = 0;
for(int i = 0;i < n;i++)
if(i%2 == 0)
temp[i] = arr[max];
max--;
else
temp[i] = arr[min];
min++;
for(int i = 0;i < n;i++)
arr[i] = temp[i];
int main()
const int n = 10;
long long arr[] = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9;
rearrange(arr, n);
return 0;
编译器g++ 9.3.0
没有显示错误,也没有引发SIGSEG
信号。
但是!
你的功能有弱点。现代 C++ 编译器允许您像以前那样声明数组:
long long temp[n];
弱点在于变量n
的值在编译期间是未知的。这是一种糟糕的 C++ 方式。最好这样做(如果您选择 C 样式的数组):
void rearrange(long long *arr, int n)
long long *temp = new long long[n];
...
...
...
delete temp;
此外,您可能调用了一个函数并传递给它一个指向随机内存位置的指针arr
,即没有为数组分配内存。例如,如果你用这样一个未初始化的指针调用你的函数,操作系统会发起一个信号SIGSEG
(Segmentation Fault):
int main()
const int n = 10;
long long *arr; // pointing to any (unknown) memory cell
rearrange(arr, n);
return 0;
但在这种情况下,g++
显示警告消息:“arr”在此函数(main)中未初始化。
【讨论】:
更好的方法是使用std::vector<long long>
和push_back
的值。
@Thomas Matthews,你能解释一下为什么它是解决这个问题的更好方法吗?当然,标准 C++ 库功能强大,提供了更多高级编程机会。我们可以在这个问题中使用矢量。但是我确信这个问题的作者是一个初学者,因为他已经提出了这个问题。那么向初学者解释什么更容易:通常的指针 - 这是语言的一部分,不需要任何库 - 或许多标准库容器之一?在我看来,我已经展示了最接近作者风格的解决方案之一。
@V.Fedulov RAII 仅举一个。总的来说,我同意Kate Gregory。
@V.Fedulov: 1) 内存管理(用于扩展)已经实现,并经过测试。您不必浪费时间进行开发和调试。 2)std::vector
有一个size
方法。当您将 std::vector
传递给函数时,您始终可以获得大小。数组需要传递数组的开头和容量(甚至可能是元素的数量)。 3) 与其他函数一起传递的语法更容易。 4) std::vector
删除它分配的所有内存。使用动态分配的数组,你必须记住何时删除内存。这够了吗?
是的,但我要求解释为什么 vector 是这个特定问题的最佳解决方案。显然,作者不再对这个问题感兴趣。我只是想说明他不使用 std 库时遇到的错误的性质。【参考方案2】:
问题很可能是数组索引越界。如果n
大于数组的大小或为负数,就会发生这种情况。
一种解决方案是使用std::vector<long long> &arr
而不是long long *arr
,这样可以使用size()
函数而不是依赖n
来等于数组大小。
【讨论】:
【参考方案3】:首先,您不能创建数组指针。数组总是通过引用传递的。按照这段代码,
void rearrange(long long arr[], int n)
// do some thing
【讨论】:
我的建议是尽可能停止使用“C”风格的数组,改用std::array/std::vector。 请注意,此函数与 OP 的签名完全相同。 你当然可以让数组衰减为指针;无论哪种方式,它在逻辑上都是等价的。以上是关于如何删除我的 C++ 代码中的分段错误?的主要内容,如果未能解决你的问题,请参考以下文章