fread第二次执行时触发段错误的问题咨询
fread第二次执行时触发段错误的问题咨询
嘿,这个坑我以前也踩过!咱们直接戳破问题核心:你把结构体里的指针直接写入文件了,这可是C语言里超级常见的新手(甚至老鸟偶尔也会犯)错误。
给你掰扯清楚为什么会炸:
- 当你执行
fwrite(&lic, sizeof(struct Lic), 1, FILE_LICENCE)的时候,写入文件的不是"USER"这个字符串本身,而是lic.u这个指针存的内存地址——也就是第一次运行时,字符串常量"USER"在进程内存里的位置。 - 等你第二次跑程序用
fread把数据读进tmp结构体,tmp.u拿到的就是那个旧的内存地址。但每个进程的内存空间是完全独立的,这个地址在新进程里要么是没被分配的野地址,要么是系统保护的只读区域,你敢碰它,操作系统直接就给你抛段错误终止程序了。
给你两个实用的修复方案,看你需求选:
- 方案一:用固定大小字符数组替代指针
把结构体里的char* u改成char u[64];(大小根据你实际存储的字符串长度调整),然后用strcpy(lic.u, "USER");把字符串拷贝进去。这样fwrite写入的就是字符串的实际内容,读回来后直接访问数组就行,稳得一批。 - 方案二:动态存储变长字符串
如果字符串长度不固定,就换个存储逻辑:先写入lic.h的整数值,再写入字符串的长度,最后写入字符串内容;读取的时候反过来,先读整数,再读长度,用malloc申请对应大小的内存,最后把字符串内容读进申请好的内存里。记得用完内存要free,别漏了哦。
最后补两个小提醒:
- 每次
fopen之后一定要检查返回值!要是文件打开失败(比如权限不够、路径错了),后续的读写操作全白搭,还容易出奇怪的错误。 - 你代码里
fwrite的最后一个参数好像打错了,应该是FILE_LICENCE不是FILE_LICE,这个笔误先改了哈。
备注:内容来源于stack exchange,提问作者Maurizio
相关产品推荐
相关产品推荐

