代码执行strcpy(buffer_two, argv[1])后触发segmentation fault,求排查
帮你搞定这个段错误问题
嘿,我来拆解你遇到的这个段错误问题,核心原因其实很明确——你的代码触发了缓冲区溢出,而且还有个隐藏的参数检查漏洞,咱们一步步说:
1. 直接导致段错误的元凶:不安全的strcpy
你定义的buffer_two是个长度为8的字符数组,这意味着它最多能装7个有效字符,加上1个字符串必须的结束符\0。但strcpy这个函数是个“愣头青”:它只会一直拷贝,直到遇到源字符串的\0为止,完全不管目标缓冲区能不能装下。
如果你传入的命令行参数argv[1]长度超过7,strcpy就会往buffer_two后面的内存地址疯狂写数据——这些内存本来是属于其他变量的(比如buffer_one、value),甚至可能覆盖栈上的函数返回地址。一旦关键内存被破坏,程序执行到main函数返回时,就会跳转到一个非法的内存地址,直接触发段错误。
2. 隐藏的坑:没检查命令行参数是否存在
你的代码没判断argc是不是≥2,也就是说如果运行程序时啥参数都不传,argv[1]就是NULL。strcpy尝试从NULL地址读数据,这也会直接触发段错误,这也是个常见的触发点。
怎么修复?
给你两个关键修改点,直接解决问题:
- 先检查参数是否存在:在用
argv[1]之前,先判断argc >= 2,没参数就提示用户 - 换用安全的拷贝函数:把
strcpy换成strncpy(记得手动加结束符)或者snprintf,严格限制拷贝的字节数不超过缓冲区大小
修改后的代码示例:
#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { int value = 5; char buffer_one[8], buffer_two[8]; strcpy(buffer_one, "one"); strcpy(buffer_two, "two"); printf("[BEFORE] buffer_two is at %p and contains '%s'\n", buffer_two, buffer_two); printf("[BEFORE] buffer_one is at %p and contains '%s'\n", buffer_one, buffer_one); // 先检查有没有传入参数 if (argc < 2) { printf("Error: 请传入一个命令行参数哦~\n"); return 1; } int input_len = strlen(argv[1]); printf("\n[STRCPY] copying %d bytes into buffer_two\n\n", input_len); // 用strncpy限制拷贝长度,手动加结束符 strncpy(buffer_two, argv[1], sizeof(buffer_two) - 1); buffer_two[sizeof(buffer_two) - 1] = '\0'; // 确保字符串正常结束 printf("[After] buffer_two is at %p and contains '%s'\n", buffer_two, buffer_two); printf("[After] buffer_one is at %p and contains '%s'\n", buffer_one, buffer_one); printf("[AFTER] value is at %p and is %d (0x%08x)\n", &value, value, value); return 0; }
验证一下
你可以试两个场景:
- 不传参数运行:原代码直接崩,修改后的代码会友好提示
- 传个超过7个字符的参数(比如
./your_program 123456789):原代码会溢出破坏其他变量甚至崩,修改后的代码会自动截断成前7个字符,完全安全
内容的提问来源于stack exchange,提问作者Smith
相关产品推荐
相关产品推荐

