博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GDB调试字符数组时指针和数组区别的体现
阅读量:5104 次
发布时间:2019-06-13

本文共 2137 字,大约阅读时间需要 7 分钟。

测试ftell函数时发现报错,先贴源码

// File Name: ftell.c                                                       #include 
#include
int main(int argc, char** argv){ FILE* fp = fopen("myfile.in", "r"); if (fp == NULL) { perror("fopen error"); exit(1); } char buf[4]; fgets(buf, 4, fp); if (fputs(buf, fp) == EOF) { perror("fputs error"); exit(1); } if (ferror(fp)) { perror("ferror"); exit(1); } return 0;}

错误信息如下 

于是用GDB调试,在fputs处设断点,输出字符数组

突然我想查看每个字符的值,于是看到的是这个

啊,突然想起来,buf的类型并不是char*,虽然如果作为函数输入参数的话会被当成char*,但是buf的实际类型是char (*)[4]

所以输出的是4个char (*)[4],也就是buf开始的16个字符

但是我使用p &buf[0]@sizeof(buf)会报错Only values in memory can be extended with '@'

想着可能需要类型转换,加了(char*)后还是报错,原来是因为只有值才能狗用@扩展,GDB会取得值的指针,然后用@往前移动

于是几个调试如下

(gdb) p buf$1 = "lin"(gdb) p &buf[0]$2 = 0x7fffffffde90 "lin"(gdb) p &buf[0]@4Only values in memory can be extended with '@'.(gdb) p (char*)&buf[0]@4Only values in memory can be extended with '@'.(gdb) p *(char*)&buf[0]@4$3 = "lin"(gdb) p *buf@4$4 = "lin"

\0是看不到的,除非单独查看那一位的字符

(gdb) p (int)buf[3]$5 = 0(gdb) p buf[3]$6 = 0 '\000'

OK,继续解决fputs出错的问题吧。

其实perror显示的信息很完美了,错误原因是Bad file descriptor,在这里文件描述符藏在FILE*指向的对象里,错误也就是fp。

这里我是要把信息输出到屏幕上,所以fputs的第二个输入参数应该是标准输出stdout,而不是我打开的文件指针fp。

由于fopen选择了读取模式,所以无法进行写入。

试着把fopen第二个参数改成"r+",允许写入,结果如下

该文本之前第1行是line 01,现在被改成了linlin1,因为读取3个字符时偏移量是3(即'e'所在位置),然后又写入了3个字符,所以"lin"替代的是"e 0"。

这里也可以发现,用"r"而不是"r+"来禁止写入能够检查出一些容易忽视的错误。

修改后如下

// File Name: ftell.c   #include 
#include
int main(int argc, char** argv) { FILE* fp = fopen("myfile.in", "r"); if (fp == NULL) { perror("fopen error"); exit(1); } char buf[4]; fgets(buf, 4, fp); if (fputs(buf, stdout) == EOF) { perror("fputs error"); exit(1); } printf("\nfile offset: %ld\n", ftell(fp)); if (ferror(fp)) { perror("ferror"); exit(1); } fclose(fp); return 0;} /* output:linfile offset: 3 */

  

转载于:https://www.cnblogs.com/Harley-Quinn/p/6492565.html

你可能感兴趣的文章
Linux常用命令与操作
查看>>
thinkphp5 composer安装验证码
查看>>
Eclipse中最常用的热键
查看>>
PL/SQL恢复默认窗口样式
查看>>
IOS--UISwitch的使用方法
查看>>
VC6工具下查看反汇编代码、机器码的使用技巧
查看>>
LeeTCode题解之Remove Duplicates from Sorted List
查看>>
Silverlight多线程技术Thread的应用
查看>>
前端知识点回顾之重点篇——CSS中vertical align属性
查看>>
我的软件终于被发布了!
查看>>
HDU_1004 Let the Balloon Rise
查看>>
SQLCLR(一)入门
查看>>
C# 串口操作系列(3) -- 协议篇,二进制协议数据解析(转)
查看>>
EasyUI实现图片的上传后与其他文本框的提交以及DataGrid中图片的展示
查看>>
fri
查看>>
最先进的开源游戏引擎KlayGE 4.4发布
查看>>
准备翻译Windows 8 动手实验系列教程
查看>>
不启动桌面系统运行qt程序
查看>>
[双硬盘GPT分区安装linux] ----安装
查看>>
Funny Car Racing CSU - 1333 (spfa)
查看>>