1、段错误
在内存管理中,操作系统为每个进程分配特定的内存区域,并进行内存访问保护。访问未分配的内存或越界访问会触发段错误,终止程序执行。
段错误通常发生在以下几种情况下:
1)访问未分配的内存,比如读取或写入空指针或无效地址。
#include <stdio.h>
int main() {
int *ptr = NULL; // 空指针
*ptr = 42; // 访问空指针,触发段错误
return 0;
}
2)访问只读内存区域,试图修改常量字符串或代码段。
#include <stdio.h>
int main() {
// 定义一个字符串常量
char *str = "Hello, world!";
// 尝试修改字符串的第一个字符
str[0] = 'h'; // 这里会产生段错误
printf("%s\n", str);
return 0;
}
3)栈溢出,例如无限递归导致的栈空间耗尽。
#include <stdio.h>
void recursiveFunction() {
printf("Recursing...\n");
recursiveFunction(); // 无限递归调用
}
int main() {
recursiveFunction();
return 0;
}
4)超出数组边界,访问数组中无效的索引位置。
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5}; // 定义一个大小为5的整数数组
// 正确访问数组元素
for (int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
// 错误:访问数组边界之外的索引
printf("arr[5] = %d\n", arr[5]); // 此处将访问第6个元素(无效的索引)
return 0;
}
2、避免段错误
段错误是由于非法内存访问导致的运行时错误,常见原因包括访问空指针、未初始化指针、数组越界、修改只读内存和栈溢出。通过初始化指针、检查指针有效性、避免越界访问等措施,可以有效减少段错误的发生。
1)初始化指针,始终初始化指针并检查其有效性。检查指针是否为 NULL
,在访问指针之前,确保它不是 NULL
。
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr = (int *)malloc(sizeof(int)); // 分配内存
if (ptr == NULL) {
printf("内存分配失败\n");
return 1;
}
*ptr = 42; // 现在可以安全地访问指针
printf("ptr 指向的值是: %d\n", *ptr);
free(ptr); // 释放内存
return 0;
}
2)避免越界访问,严格遵守数组的边界,避免超出索引范围。
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
int index;
printf("请输入索引 (0 到 4): ");
scanf("%d", &index);
// 检查索引是否在数组边界内
if (index >= 0 && index < 5) {
printf("arr[%d] = %d\n", index, arr[index]);
} else {
printf("错误: 索引超出范围\n");
}
return 0;
}
3)避免修改常量字符串,将字符串常量复制到字符数组中再修改。
#include <stdio.h>
int main() {
// 使用字符数组存储字符串内容
char str[] = "Hello, world!";
// 可以安全地修改字符数组中的元素
str[0] = 'h';
printf("%s\n", str); // 输出 "hello, world!"
return 0;
}
4)控制递归深度,在递归函数中加入基准条件,防止无限递归。
#include <stdio.h>
// 定义最大递归深度
#define MAX_DEPTH 10
void recursiveFunction(int depth) {
// 基准条件:如果达到最大深度,停止递归
if (depth >= MAX_DEPTH) {
printf("Reached maximum recursion depth of %d\n", MAX_DEPTH);
return;
}
// 打印当前递归深度
printf("Recursion depth: %d\n", depth);
// 递归调用,并将深度增加1
recursiveFunction(depth + 1);
}
int main() {
// 从深度0开始递归
recursiveFunction(0);
return 0;
}