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并不是遇到'\0'就结束,而是一定会拷贝完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结尾处的'\0')并添加'\0'
src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。 返回dest指针

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

 

posted @ 2013-06-21 20:51  夜雨阑珊  阅读(198)  评论(0编辑  收藏  举报