C学习笔记--当memset遇上strlen

当为字符数组动态开辟一块内存空间时:

char *pTemp = new char[8192];

如果想要初始化这一块内存,想当然的就写了如下代码:

memset(pTemp,0,strlen(pTemp));
动态开辟的空间用完之后记得释放:

if(pTemp)
	{
		delete[] pTemp;
		pTemp=NULL;
	}

大家能看出这段代码有问题么?

我们通常用一个char类型的数组来存放一些列char,并且在末尾放上一个0,表示结束。

当使用strlen时,由于pTemp指向的那一片连续内存空间里的值是未知的,strlen就会从pTemp指向的内存开始往后一个字节一个字节地读,直到读到结束符0,strlen的返回值便是已经读过的字符个数也就是“字符串”的长度了。

但是至于什么时候读到结束符0,就不得而知了,内存单元里存放的是什么就是什么,因此strlen返回的结果就错了。所以当你delete[] pTemp,就会出错。

解决的方便很简单,就是你想开辟多大的空间,在memset里就直接写上该空间的大小:

memset(pTemp,0,8192);

 

另外,顺便科普下delete和delete[]

int  *p=new int[100];
	int  num[100];
	p=num;
	delete []p;

错误是发生在delete []p,为什么呢?按理说用new[]申请,用delete[]释放,应该没有问题啊。但是错误发生的原因是因为delete[]p释放的是数组num[100]的空间,而我们申请的空间根本就没有释放,为什么会出现这种情况呢?因为此时的指针已指向了num数组的首地址,而num[100]的空间会由系统自动释放,而我们现在强行释放,所以会发生错误。

int *p=new int[3];
	*p=1;
	p++;//p的指向改变了,指向了下一空间
	*p=2;
	delete []p;

错误还是发生在delete[]p,c/c++规定,当删除一个指针时,这个指针应指向其首地址,而上面的代码中p值已经发生了变化,所以会发生错误,如何避免呢?可以备份一份;如 int * pbak=p;在释放的时候,用delete[]pbak即可。

int* p = new int(10);
    int *pp=p;
    delete []p;
    delete []pp;

我们要知道,p向操作系统申请了10个int类型的空间,而pp只是指向这个空间,操作系统并没有为其再分配10个int类型的空间,所以当你用delete[]p释放这个空间后,再用delete[]pp释放就会发生错误。其实不管用哪个释放,只要释放一次就行了。

int a=100;
    int *p=&a;
    delete p;

看到了这里,如果你还不能看出这段代码的错误,那你前面的白看了,说明你还是没有真正懂得啊!
错误还是发生在delete p,什么原因?因为p并没有通过new获得内存空间,只是指向某个变量,而delete p是强行释放a的空间,肯定发生错误啦。

delete 和 delete[] 区别

我们首先要知道当delete的时候,系统会自动调用已分配的对象的析构函数。
那么当我们用new[]分配的对象是基本数据类型的时候,用delete和delete[]没什么区别,都可以。但是当用new[]分配的对象是自定义类型的时候,必须要用delete[],这样它才会调用每个对象的析构函数,除非你的析构函数没有做任何事。

总结一句话:使用 new 得来的空间,用 delete 来释放;使用 new [] 得来的空间,必须用 delete [] 来释放。这样肯定不会错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值