《C++ Primer》第12章 动态内存
12.2节 动态数组 习题答案
练习12.23:编写一个程序,连接两个字符串字面常量,将结果保存在一个动态分配的char数组中。重写这个程序,连接两个标准库string对象。
【出题思路】
本题练习使用动态数组。
【解答】
用new char[xx]即可分配用来保存结果的char数组,其中xx应该足以保存结果字符串。由于C风格字符串以'\0'结尾,因此xx应不小于字符数加1。对字符串字面常量(即字符数组),可以使用strcpy将第一个字符串拷贝到动态数组中,然后用strcat将第二个字符串连接到动态数组中。对两个string对象,使用+运算即可简单实现连接。然后用c_str获取连接结果(临时string对象)的内存地址,用strcpy拷贝到动态数组即可。最终,不要忘记释放动态数组。
#include <iostream>
#include <cstring>
using std::cout;
using std::endl;
using std::string;
int main()
{
const char *c1 = "Hello ";
const char *c2 = "World";
//字符串所需空间=字符数+1
char *r = new char[strlen(c1) + strlen(c2) + 1];
strcpy(r, c1);//拷贝第一个字符串常量
strcat(r, c2);//连接第二个字符串常量
cout << "r=====" << r << endl;
string s1 = "hello ";
string s2 = "world";
strcpy(r, (s1 + s2).c_str());
cout << "r=====" << r << endl;
//释放动态数组
delete []r;
return 0;
}
运行结果:
练习12.24:编写一个程序,从标准输入读取一个字符串,存入一个动态分配的字符数组中。描述你的程序如何处理变长输入。测试你的程序,输入一个超出你分配的数组长度的字符串。
【出题思路】
本题继续练习使用动态数组。
【解答】
我们处理变长输入的方法是,根据动态分配的字符数组的大小确定字符串长度阈值,当读取的字符数超出阈值时,停止读取,即采取了截断的方式。还可采取其他处理方式,如抛出异常等。另外,为了能读取空格等空白符,程序中用到了get操作来读取字符。
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char c;
//分配20个字符的动态数组,因此最多存放19个字符
char *arr = new char[20];
int len = 0;
while(cin.get(c))
{
if(isspace(c))//字格符,制表符等空白符
break;
arr[len++] = c;//存入动态数组
if(len == 19)
{
cout << "达到数线容量上限" << endl;
break;
}
}
arr[len] = '\0';
cout <<"len = " << len << " arr=======" << arr;
//释放动态数组
delete []arr;
return 0;
}
运行结果:
练习12.25:给定下面的new表达式,你应该如何释放pa?
int *pa = new int[10]
【出题思路】
理解释放动态数组的特殊方式。
【解答】
delete []pa;
练习12.26:用allocator重写第427页中的程序。
【出题思路】
本题练习使用allocator。
【解答】
首先,定义一个allocator<string> alloc。然后,用alloc的allocate而不是new操作来分配内存。这样,只会分配裸内存,而不会初始化string对象。接下来,用construct操作从读取的string对象来初始化动态数组中的string。随后动态数组的使用就和往常一样了。使用完毕后,记住与内存分配和对象构造一样,对象析构(使用destroy操作)和内存释放(deallocate操作)也是分开的。
#include <iostream>
#include <string>
#include <memory>
using namespace std;
int main()
{
allocator<string> alloc;
//分配100个未初始化的string
auto const p = alloc.allocate(100);
string s;
string *q = p; //q指向第一个string
while(cin >> s && q != p + 100)
{
alloc.construct(q++, s); //用s初始化*q
}
const size_t size = q - p; //记住读了多少个string
cout << "size = " << size << endl;
cout << endl;
//使用数组
for(size_t i = 0; i < size; i++)
cout << p[i] << "\t";
while (q != p) {
alloc.destroy(--q);
}
alloc.deallocate(p, 100);
cout << "hello world" << endl;
return 0;
}
运行结果: