zoukankan      html  css  js  c++  java
  • C++基础学习-20120516

    1、
    一下是使用strcpy_s与strcpy的安全性比较

     char szBuf[2] = {0};

     strcpy_s(szBuf, 2, "12131");  //新的CRT函数
     strcpy(szBuf,  "12131");    //老的CRT函数

    上述代码,明显有缓冲区溢出的问题。 使用strcpy_s函数则会抛出一个异常。而使用strcpy函数的结果则未定,因为它错误地改变了程序中其他部分的内存的数据,可能不会抛出异常但导致程序数据错误,也可能由于非法内存访问抛出异常。

    使用新的增强安全的CRT函数有什么好处呢?简单地说,新的函数加强了对参数合法性的检查以及缓冲区边界的检查,如果发现错误,会返回errno或抛出异常。老版本的这些CRT函数则没有那么严格的检查与校验,如果错误地传输了参数或者缓冲区溢出,那么错误并不能被立刻发现,对于定位程序错误也带来更大困难。

    2---------
    assert断言的使用:
    1:assert是宏,而不是函数。
    void assert( int expression );   
    assert的作用是先计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,   
    然后通过调用 abort 来终止程序运行。
    使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。
    1)在函数开始处检验传入参数的合法性
    2)每个assert最好只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败
    3)不能使用改变环境的语句,因为assert只在DEBUG个生效,如果这么做,会使用程序在真正运行时遇到问题
    4)assert和后面的语句应空一行,以形成逻辑和视觉上的一致感
    5)有的地方,assert不能代替条件过滤

    3-----------悬挂指针

    与内存泄露相比,C++最令人头痛的问题是内存越界,而内存越界很多情况下是由于悬挂指针引起的。  
    假设一个指针变量: Object * ptr;
    使用ptr时,我们除了要判断ptr是否为0以外,还要怀疑它指向的对象是否有效,是不是已经在别的地方被销毁了。我们希望当它指向的对象被销毁时,ptr被自动置为0。
    所谓指针悬挂是指指针指向了一块没有分配给用户使用的内存

    4---------野指针
    成因:
    1指针变量没有初始化。不指向null可能指向任何位置
    2被free或delete之后,没有置为null,被认为是合法的指针
    3指针操作超越了变量的作用范围。

    5------------
    strcpy与memcpy的区别
    void *memcpy(void *dest, const void *src, int n);与strcpy相比,memcpy并不是遇到''就结束,而是一定会拷贝完n个字节
    如果目标数组destin本身已有数据,执行memcpy()后,将覆盖原有数据(最多覆盖n)。如果要追加数据,则每次执行memcpy后,要将目标数组地址增加到你要追加数据的地址

    6----------
    memset的使用 
    void *memset(void *s, int ch, size_t n); 作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
    因为第一个程序的 数组a是字符型的,字符型占据内存大小是1Byte,而memset函数也是以字节为单位进行赋值的,所以你输出没有问题。而第二个程序a是整型的,使用 memset还是按字节赋值,这样赋值完以后,每个数组元素的值实际上是0x01010101即十进制的16843009。你看看你输出结果是否这样?   
    2.如果用memset(a,1,20);  a是int型的4字节 就是对a指向的内存的20个字节进行赋值,每个都用ASCII为1的字符去填充,转为二进制后,1就是00000001,占一个字节。一个INT元素是4 字节,合一起就是00000001000000010000000100000001,就等于16843009,就完成了对一个INT元素的赋值了
    memset(s,'G',6);//可以对字符串给定字符值,char和int可以相互转换啊

    7------------
    sprintf的用法:把数据打印到字符串中
    int sprintf( char *buffer, const char *format, [ argument] … ) ;
    char s[100];
    sprintf(s,"%d",123);把123以十进制方式右对齐打印到字符串s中
    sprintf(s,"-%d",123);左对齐
    sprintf(s,"%d%d",123,234);第3,4个参数个数可变
    连接字符串比strcat好用
    sprintf(s,"%s love %s","i","wyy");
    sprintf 在MFC 中也能找到他的知音:CString::Format
    sprnitf 还有个不错的表妹:strftime,专门用于格式化时间字符串的
    time_t t = time(0);
    //产生"YYYY-MM-DD hh:mm:ss"格式的字符串。   
    char s[32];
    strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", localtime(&t));

    8----------
    extern char *strcat(char *dest,char *src);
    把src所指字符串添加到dest结尾处(覆盖dest结尾处的'')并添加''
    src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 返回dest指针

    9-----------
    字符串和字符数组的区别:
    字符数组char ch[]={'a','b','c','d',''};//必须手动指定结束符
    char ch[]={"abcdefg"};一维的字符数组
    char ch[][]={"asada","dasfa"};二维的数组
    字符串char ch="abcdefg";默认带有结束符
    char ch[]={'a','b','c','d'}strlen为啥是13,VS下编译???????????????

  • 相关阅读:
    Linux下制作和使用静态库和动态库
    C语言的内存管理
    C语言柔性数组
    大小端模式
    C位域操作
    C/C++字节对齐
    C/C++指针
    Linux之Socket编程
    VSCode配置FTP
    GCC的编译过程和链接
  • 原文地址:https://www.cnblogs.com/fickleness/p/3148977.html
Copyright © 2011-2022 走看看