[C++ 学习] C++ Primer 第4版 习题 4.30 字符串操作 & 我对堆内存 和 常量区内存的一些理解

首先随便说一个和这个习题无关的内容.

 

看下面一段代码,找找问题:

int main()
{
	char *str = "test";
	delete str;

	return 0;
}


这段代码会出现什么样的问题呢?

在 delete str;的时候,程序会 Crash 掉。

 

原因是因为 "test" 是一个常量,

这个常量并不驻留在 Stack 栈内存,也不驻留 在 Heap 堆内存,

而是驻留在 常量区 (记得学习 win32 汇编的时候,常量区需要一个非常明显的声明和定义,但是在 C/C++里面没有),

所以不能指望函数执行完毕收回内存,更不能被视作 Heap 堆内存由程序来 delete.

之所以出错,就是因为这里对 常量区 的内存,进行了 delete.

 

由此我根据我浅薄的C++语言知识 ,来猜测一下 delete 操作符的作用。

delete操作符,用于释放 Heap内存,至于这里面的值改变不改变,跟delete 没关系。

只是告诉 系统 可以去再次利用这块内存了。

所以这块内存的值是可能在 delete 的时候 被改变的。

 

 

但是delete 这种修改,即使是 常量指针,也可以进行 delete .

比如下面这段代码:

int main()
{
	const int *p = new int(3);			//	alloc Heap memory,save int value 3

	*p = 5;							//	wrong .Cause const pointer shouldn't modify the value .

	delete p;						//	okay,we release the Heap memory.
									//	Although delete maybe modify the value,
									//	delete is still right.

	return 0;
}


int *p =new int(3);

在 Heap 内存上 分配了空间。它和 上面说的 char *str = "test";不一样,这次是分配在 堆内存上

*p =5 ;

const int * p 这种 常量指针,不能够通过指针来修改对象的值。这在编译的时候就会引起错误。

delete p;

释放对内存,让这块内存允许被系统回收使用。

即使 delete p ;导致了 *p所指向的内存的内容 被修改了,

这样依然是允许的,它和使用  *p = x;表达式来修改  p 所指向的对象的值 的含义是不同的。

 

====================================================================================================================

以上随便说了说自己对 内存 和 delete 操作符的理解。

因为在习题中,自己无知地 delete 常量区 内存了,所以引发了一些思考和牢骚。

下面是 习题相关的内容。

====================================================================================================================

 

这个习题需要注意以下知识点 :

1.

strlen()计算出来的 字符串长度 是不包括 结尾的 null的。

 

2.

在使用 strcpy strcat 这种函数的时候,一定要给目标存储区足够大的空间。

否则会有内存上的问题。

 

3.

strncpy

strncat

需要传一个长度参数 ,这个长度需要包含 源字符串最后的 null.

比如

这里的 strncpy(strCStyle,str1,len1+1);

再比如即使只穿一个字符的字符串,也需要把长度参数设置为2 。

strncat(destStr,"",2);

 

4.

C 语言风格的 char * 字符串,可以直接赋值给 STL 的  string.

但是 STL 的  string  赋值给  C 语言风格的 char * 字符串,需要调用

string::c_str() 函数

 

 

5.

C 语言风格的 char* 字符串动态数组 需要 手动删除 Heap内存,

而 STL string 不用关心 内存管理。

 

#include<iostream>
#include<string>
#include<vector>

using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::string;

int main()
{
	const char *str1 = "myl";
	const char *str2 = "gj";

	size_t len1 = strlen(str1);
	size_t len2 = strlen(str2);

	//	result hold by C Style string
	char *strCStyle = new char[len1+len2+1]();
	
	strncpy(strCStyle,str1,len1+1);
	strncat(strCStyle,str2,len2+1);

	cout << "Result of C Style string : " <<strCStyle<< endl;

	//	result hold by string (STL)
	string strResult,strSrc1,strSrc2;
	strSrc1 = str1;
	strSrc2 = str2;
	strResult = strSrc1+strSrc2;
	cout << "Result of C++ string : " <<strResult<< endl;

	delete [] strCStyle;

	return 0;
}


 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值