我的数组程序中出现这个stack smashing错误的原因是什么?
What is the reason for this stack smashing error in my array program?
我有一个数组,它插入一个值并移动元素。虽然它可以编译,但我有一些警告。这是我的代码:
#include <iostream>
void display_array(int arr[], int max_length = 10);
void insert_array(int arr[], int insert_num, int index_num, int max_length = 10);
int main() {
int arr_length = 10;
int new_score, index;
int test_scores[arr_length] = {86, 71, 92, 84, 88, 96};
display_array(test_scores);
std::cout << "Enter new test score: ";
std::cin >> new_score;
std::cout << "\nEnter index position: ";
std::cin >> index;
insert_array(test_scores, new_score, index);
display_array(test_scores);
return 0;
}
void display_array(int arr[], int max_length) {
std::cout << "Test scores in array: ";
for(int i = 0; i < max_length; i++) {
std::cout << arr[i] << " ";
}
std::cout << "\n";
}
void insert_array(int arr[], int insert_num, int index_num, int max_length) {
for(int i = max_length; i > index_num; i--) {
arr[i] = arr[i - 1];
}
arr[index_num] = insert_num;
}
在 VS Code 中我收到警告:“变量“test_scores”可能不是 initializedC/C++ (145)”
我将我的 'arr_length' 变量更改为常量并且它消失了,但是尽管我的代码在更改后仍然可以编译并执行其所有功能,但在我的程序结束时我得到
*** stack smashing detected ***: terminated
Aborted (core dumped)
gdb 给了我这样的东西:
Program received signal SIGABRT, Aborted.
0x00007ffff7acd615 in raise () from /usr/lib/libc.so.6
我检查了这个 link When does a process get SIGABRT (signal 6)? 似乎是内存问题。但是当我查看我的数组和 for 循环的结构时,它们似乎在边界内,而且看起来我并没有尝试访问不存在的东西……是什么导致了这个错误?
您的代码执行此操作
for(int i = max_length; i > index_num; i--) {
arr[i] = arr[i - 1];
}
其中 max_length
等于 10。但是您的数组大小为 10,因此最大有效索引为 9。更改为
for(int i = max_length - 1; i > index_num; i--) {
arr[i] = arr[i - 1];
}
当程序向位于堆栈上的缓冲区写入比实际分配给该缓冲区的数据更多的数据时,会导致堆栈缓冲区溢出错误。 gcc
添加了检测堆栈溢出错误的保护机制。
gcc
编译器添加了称为 canary 的保护变量,这些变量具有已知值。如果您写入超出分配的内存,金丝雀的价值就会改变。这将触发堆栈粉碎(修改金丝雀变量)。
for(int i = max_length; i > index_num; i--)
{
arr[i] = arr[i - 1];
}
这里,max_length = 10
,所以arr[i]
的意思是arr[10]
超出了数组的大小。您实际上是在访问超出限制的内存。这将修改 canary 变量的值。这就是为什么您会遇到堆栈粉碎错误的原因。
我有一个数组,它插入一个值并移动元素。虽然它可以编译,但我有一些警告。这是我的代码:
#include <iostream>
void display_array(int arr[], int max_length = 10);
void insert_array(int arr[], int insert_num, int index_num, int max_length = 10);
int main() {
int arr_length = 10;
int new_score, index;
int test_scores[arr_length] = {86, 71, 92, 84, 88, 96};
display_array(test_scores);
std::cout << "Enter new test score: ";
std::cin >> new_score;
std::cout << "\nEnter index position: ";
std::cin >> index;
insert_array(test_scores, new_score, index);
display_array(test_scores);
return 0;
}
void display_array(int arr[], int max_length) {
std::cout << "Test scores in array: ";
for(int i = 0; i < max_length; i++) {
std::cout << arr[i] << " ";
}
std::cout << "\n";
}
void insert_array(int arr[], int insert_num, int index_num, int max_length) {
for(int i = max_length; i > index_num; i--) {
arr[i] = arr[i - 1];
}
arr[index_num] = insert_num;
}
在 VS Code 中我收到警告:“变量“test_scores”可能不是 initializedC/C++ (145)”
我将我的 'arr_length' 变量更改为常量并且它消失了,但是尽管我的代码在更改后仍然可以编译并执行其所有功能,但在我的程序结束时我得到
*** stack smashing detected ***: terminated
Aborted (core dumped)
gdb 给了我这样的东西:
Program received signal SIGABRT, Aborted.
0x00007ffff7acd615 in raise () from /usr/lib/libc.so.6
我检查了这个 link When does a process get SIGABRT (signal 6)? 似乎是内存问题。但是当我查看我的数组和 for 循环的结构时,它们似乎在边界内,而且看起来我并没有尝试访问不存在的东西……是什么导致了这个错误?
您的代码执行此操作
for(int i = max_length; i > index_num; i--) {
arr[i] = arr[i - 1];
}
其中 max_length
等于 10。但是您的数组大小为 10,因此最大有效索引为 9。更改为
for(int i = max_length - 1; i > index_num; i--) {
arr[i] = arr[i - 1];
}
当程序向位于堆栈上的缓冲区写入比实际分配给该缓冲区的数据更多的数据时,会导致堆栈缓冲区溢出错误。 gcc
添加了检测堆栈溢出错误的保护机制。
gcc
编译器添加了称为 canary 的保护变量,这些变量具有已知值。如果您写入超出分配的内存,金丝雀的价值就会改变。这将触发堆栈粉碎(修改金丝雀变量)。
for(int i = max_length; i > index_num; i--)
{
arr[i] = arr[i - 1];
}
这里,max_length = 10
,所以arr[i]
的意思是arr[10]
超出了数组的大小。您实际上是在访问超出限制的内存。这将修改 canary 变量的值。这就是为什么您会遇到堆栈粉碎错误的原因。