GDB调试字符数组时指针和数组区别的体现
测试ftell函数时发现报错,先贴源码
// File Name: ftell.c
#include <stdio.h>
#include <stdlib.h> 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]@4
Only values in memory can be extended with '@'.
(gdb) p (char*)&buf[0]@4
Only 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 <stdio.h>
#include <stdlib.h> 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:
lin
file offset: 3
*/
GDB调试字符数组时指针和数组区别的体现的更多相关文章
- [C++]指针和指向数组的指针[一维数组与指针]
1.一维数组与指针 形如:int型 数组 a[10] 1)&a[0] 地址常量;地址类型:int *型 ; 存储数组a的首地址 ...
- C/C++拾遗(一):关于数组的指针和数组元素首地址的一道经典题
代码例如以下: #include <stdio.h> int main(void) { int a[5] = {1, 2, 3, 4, 5}; int *ptr = (int *)(&am ...
- Vscode 调试 C 语言时数组值无法显示的问题
使用 Vscode 的 Gdb 扩展调试 C 语言时,发现数组变量在 变量列表里面中显示为指针,且只显示为其第一个元素的值,无法看到所有元素的值. 如图所示: 解决: 假设有一个元素个数为10的数组v ...
- gdb 调试(查看运行时数据) 四
在使用GDB调试程序时,触发断点后,可以使用print命令(简写为p),或是同义命令inspect来查看当前程序的运行数据.print命令的格式是: print <expr> pri ...
- C++数组和指针
<C++ Primer 4th>读书摘要 与 vector 类型相似,数组也可以保存某种类型的一组对象:而它们的区别在于,数组的长度是固定的.数组一经创建,就不允许添加新的元素.指针则可以 ...
- C/C++中数组与指针的关系探究
数组与指针 长期以来,在C/C++中,数组名和指向数组首元素的指针常量到底是以一种什么关系,一直困扰着很多人.很多地方,甚至是一些教科书中都在说,"数组名就是一个指向数组首元素的指针常量&q ...
- C Primer Plus学习笔记(九)- 数组和指针
数组 数组由数据类型相同的同一系列元素组成 需要使用数组时,通过声明数组告诉编译器数组中内含多少元素和这些元素的类型 普通变量可以使用的类型,数组元素都可以用 float candy[365]; // ...
- C中 数组和指针的异同
数组在很多情况下是和指针等价的,数组的下标运算和指针的解引用也有等价形式:arr[i] == *(arr + 1):但是也有一些情况下数组和指针是不一样的:extern int arr[]; exte ...
- C++数组(指针)作为函数参数
本文的学习内容参考:http://blog.csdn.net/wwdlk/article/details/6322843 1.当用数组名作为函数参数时,函数的实参和形参都应为数组名(或者指针): Ex ...
随机推荐
- laravel中上传图片之后图片的处理
$file=Input::file('file'); if ($file->isValid()){ $entension=$file->getClientOriginalExtension ...
- USB events thread - failed to set priority
ubuntu + openni + nite,出现 Warning:USB events thread - failed to set priority xn::ImageGenerator imag ...
- h5和app原生联调触发方法
//路径跳转 urlHref(item) {//人物.访谈.动态是一个页面 var para = {}; para.title = "动态详情"; para.type = &quo ...
- PHP 中使用explode()函数切割字符串为数组
explode()函数的作用:使用一个字符串分割另一个字符串,打散为数组. 例如: 字符串 $pizza = "第1 第2 第3 第4 第5 第6"; 根据空格分割后:$piece ...
- jquery 判断checkbox状态
jquery判断checked的三种方法:.attr('checked): //看版本1.6+返回:”checked”或”undefined” ;1.5-返回:true或false.prop('c ...
- C++解决error C4996报错
今天用c++写了个数独程序,在编译过程中报了一个错误: 1>------ 已启动生成: 项目: sudoku, 配置: Debug Win32 ------1> main.cpp1> ...
- [置顶]
【机器学习PAI实践八】用机器学习算法评估学生考试成绩
(本文数据为实验用例) 一.背景 母亲是老师反而会对孩子的学习成绩造成不利影响?能上网的家庭,孩子通常能取得较好的成绩?影响孩子成绩的最大因素居然是母亲的学历?本文通过机器挖掘算法和中学真实的学生数据 ...
- 用前序和中序重建二叉树 python
程序实现了用二叉树的前序遍历序列和中序遍历序列重建二叉树,代码用python实现. 首先定义二叉树节点的类: class TreeNode: def __init__(self, x): self.v ...
- C#中PadLeft和PadRight小知识点
当我们显示字符串数据时,有时候我们需要考虑数据的排列美观. 比如一些人名和一些编号,我们想让他们整齐对齐显示等. C# String类提供了2种操作方法: String.PadLeft(int tot ...
- 创建第一个python程序:‘Hello World!’
安装好python解释器就可以创建第一个仪式程序Helloworld了 1.Python程序的3种运行方式 1.1.Python解释器直接运行 在Windows或者Linux命令行输入python,进 ...