zsh: bus error ./a.out错误排查及C语言类型转换内存疑问
问题分析与解答
总线错误的原因
你遇到的zsh: bus error是因为修改了只读内存区域的内容:
- 主函数中
str = "0123456789abcdefghijklmnopqrstuvwxyz";里的字符串是字符串字面量,这类数据会被编译器放在程序的只读数据段(.rodata)中,操作系统会禁止对该区域的写入操作。 - 你的
ft_print_memory函数里,memory = (char *)addr;只是把指针类型转换为char*,并没有复制原字符串,memory仍然指向那个只读的字符串字面量。执行memory[16] = '\0';时试图写入只读内存,直接触发内存访问错误。
你的疑问解答
1. 类型转换会在栈还是堆上创建变量?
不会。类型转换(char *)addr只是编译时的类型解释,没有任何内存分配操作,也不会创建新变量:
memory只是一个栈上的指针变量,它存储的地址和addr完全相同,指向的是原内存区域,没有生成任何新的内存空间。
2. 类型转换是否会像malloc一样生成有效的字符串?
完全不会。malloc的作用是在堆上分配新的内存空间,而类型转换不分配任何内存,也不会复制原数据:
- 你这里的
memory只是原字符串的指针,不是新的字符串副本。如果原字符串是只读的,转换类型后仍然无法修改它。
修复方案
要修改字符串内容,必须先创建一个可修改的副本,有两种常见方式:
方式1:使用栈上的数组
把字符串字面量复制到栈上的可修改数组中:
int main (int argc, const char *argv[]) { char str[] = "0123456789abcdefghijklmnopqrstuvwxyz"; ft_print_memory(str, 16); return (0); }
方式2:使用堆内存(malloc)
适合字符串长度不确定或需要长期保存的场景:
#include <stdlib.h> #include <string.h> int main (int argc, const char *argv[]) { const char *original = "0123456789abcdefghijklmnopqrstuvwxyz"; // 分配足够内存(包含末尾的'\0') char *str = malloc(strlen(original) + 1); if (str == NULL) { return 1; // 处理内存分配失败 } strcpy(str, original); ft_print_memory(str, 16); free(str); // 用完释放堆内存 return (0); }
内容的提问来源于stack exchange,提问作者RoGKôT
相关产品推荐
相关产品推荐

