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

  • 相关阅读:
    417 Pacific Atlantic Water Flow 太平洋大西洋水流
    416 Partition Equal Subset Sum 分割相同子集和
    415 Add Strings 字符串相加
    414 Third Maximum Number 第三大的数
    413 Arithmetic Slices 等差数列划分
    412 Fizz Buzz
    410 Split Array Largest Sum 分割数组的最大值
    409 Longest Palindrome 最长回文串
    day22 collection 模块 (顺便对比queue也学习了一下队列)
    day21 计算器作业
  • 原文地址:https://www.cnblogs.com/westfly/p/1897443.html
Copyright © 2011-2022 走看看