zoukankan      html  css  js  c++  java
  • gdb与memset以及sizeof

    调试一个简单的程序,犯的错误一大堆。还是基础部牢固啊。

    调试的代码如下

    const int size = 256;
    int hashtable[size];
    memset(hashtable,0,sizeof(hashtable));

    很简单的,就是对一段内存赋值为0。

    由于运行的结果不对。于是用GDB来调试,怀疑是memset没有成功。于是用GDB打印数组的信息。

    (gdb) p hashtable @12
    $1 = {0x22fac0, 0x22fed0, 0x401546, 0x100, 0x100, 0x22ff48, 0x4012e0,
    0x22ff30, 0x2, 0x7f1aa0, 0x4012b5, 0x501cce74}
    (gdb) p *0x22fac0
    $2 = 0
    (gdb) p *0x501cce74
    Cannot access memory at address 0x501cce74

    从图中看,的确没有成功,hashtable中的元素都不是0,而是类似于地址的东西,然后用地址访问,有些能够成功,有些不能成功,于是否定了是地址的可能性。当然,我也尝试用char类型来做,但是效果依然如此。

    但是用

    for(int i = 0;i < 10 ; ++i)
    {
    printf("%d\t",hashtable[i]);
    }

    来打印的时候,发现输出为

    D:\Testing>a.exe
    0 0 0 0 0 0 0 0 0 0

    这证明GDB的输出是错误的(可能是在Windows下,有些问题也不一定呢!)

    不是GDB的错误,打印数组的命令格式为 print *name@len ,对应到此即  p *hashtable @12

    切记切记。

    再就说sizeof的问题。

    用得比较多的是char类型的

    在这里我声明的是int类型,我以为sizeof(hashtable)将返回size,所以我memset的最后一个参数用了表达式sizeof(int)*sizeof(hashtable),结果弄得数组越界。下次一定要记住sizeof返回的是所占内存的字节数。

    再谈谈memset。

    memxxx包括memset ,memcpy,memmove等相关函数,要用的话,包含<memory.h>或<string.h>头文件。

    表头文件 #include<string.h>
    定义函数 void * memset (void *s ,int c, size_t n);
    函数说明 memset()会将参数s所指的内存区域前n个字节以参数c填入,然后返回指向s的指针。在编写程序时,若需要将某一数组作初始化,memset()会相当方便。
    返回值 返回指向s的指针。
    附加说明 参数c虽声明为int, 但必须是unsigned char ,所以范围在0到255之间。

    表头文件 #include<string.h>
    定义函数 int memcmp (const void *s1,const void *s2,size_t n);
    函数说明 memcmp()用来比较s1和s2所指的内存区间前n个字符。字符串大小的比较是以ASCII码表上的顺序来决定,次顺序亦为字符的值。 memcmp()首先将s1第一个字符值减去s2第一个字符的值,若差为0则再继续比较下个字符,若差值不为0则将差值返回。

    表头文件 #include<string.h>
    定义函数 void * memchr(const void *s,int c,size_t n);
    函数说明 memchr()从头开始搜寻s所指的内存内容前n个字节,直到发现第一个值为c的字节,则返回指向该字节的指针。
    返回值 如果找到指定的字节则返回该字节的指针,否则返回0。

    表头文件: #include <string.h>
    定义函数: void *memcpy(void *dest, const void *src, size_t n)
    函数说明: memcpy()用来拷贝src所指的内存内容前n个字节到dest所指的内存地址上。与strcpy()不同的是,memcpy()会完整的复制n个字节,不会因为遇到字符串结束'\0'而结束
    返回值: 返回指向dest的指针

    表头文件: #include <string.h>
    定义函数: void *memccpy(void *dest, const void *src, int c, size_t n);
    函数说明: memccpy()用来拷贝src所指的内存内容前n个字节到dest所指的地址上。与memcpy()不同的是,memccpy()如果在src中遇到某个特定值(int c)立即停止复制。
    返回值: 返回指向dest中值为c的下一个字节指针。返回值为0表示在src所指内存前n个字节中没有值为c的字节。

    表头文件: #include <string.h>
    定义函数: void *memmove(void *dest, const void *src, size_t n);
    函数说明:memmove()是从一个缓冲区移动到另一个缓冲区中。
    返回值: 返回指向dest指针。

    当dest <= src-count 或dest >= src+count时,以上三个函数均不会产生覆盖问题,即源数据不会被更改。
    若不在以上范围内,则源数据会被更改。

    编译for(int i = 0;i < 10 ; ++i)
    {

    ……
    }

    当出现

    error: 'for' loop initial declaration used outside C99 mode时,有三种解决方法

    1.改成.cpp文件,用g++编译

    2.将int声明外提

    3.给gcc添加--std=c99编译选项

    参考文献

    1.memset,memmove, memcpy, memccpy, memcmp, memchr

  • 相关阅读:
    风雨中,苦算什么!!!
    痛心疾首+无奈绝望!!!
    PHP页面跳转总结
    Java的HttpClient的实现
    java细节篇(==和equals的区别)
    cmd命令笔记
    Python的HttpClient实现
    常用linux命令
    Go的HttpClient实现
    android问题笔记集
  • 原文地址:https://www.cnblogs.com/westfly/p/1897443.html
Copyright © 2011-2022 走看看