zoukankan      html  css  js  c++  java
  • 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"
    

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

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

    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("
    file offset: %ld
    ", ftell(fp));
        if (ferror(fp)) {
            perror("ferror");
            exit(1);
        }
      
        fclose(fp);
      
        return 0;
    } 
    /* output:
    lin
    file offset: 3                                                              
    */
    

      

  • 相关阅读:
    《DSP using MATLAB》 示例 Example 9.12
    《DSP using MATLAB》示例 Example 9.11
    《DSP using MATLAB》示例 Example 9.10
    《DSP using MATLAB》示例Example 9.9
    《DSP using MATLAB》示例 Example 9.8
    《DSP using MATLAB》示例Example 9.7
    《DSP using MATLAB》示例 Example 9.6
    《DSP using MATLAB》示例Example 9.5
    《DSP using MATLAB》示例 Example 9.4
    (转载)【C++11新特性】 nullptr关键字
  • 原文地址:https://www.cnblogs.com/Harley-Quinn/p/6492565.html
Copyright © 2011-2022 走看看