zoukankan      html  css  js  c++  java
  • C++Primer第五版——习题答案详解(十一)


    习题答案目录:https://www.cnblogs.com/Mered1th/p/10485695.html

    第12章 动态内存


    练习12.1
    b1包含4个元素,b2被销毁

    练习12.2

    #include <string>
    #include <initializer_list>
    #include <memory>
    #include <vector>
    #include <stdexcept>
    
    class StrBlob
    {
    public:
    	typedef std::vector<std::string>::size_type size_type;
    	StrBlob();
    	StrBlob(std::initializer_list<std::string> il);
    	size_type size() const { return data->size(); }
    	bool empty() const { return data->empty(); }
    	void push_back(const std::string &t) { data->push_back(t); }
    	void pop_back();
    	std::string& front();
    	std::string& back();
    	const std::string& front() const;
    	const std::string& back() const;
    private:
    	std::shared_ptr<std::vector<std::string>> data;
    	void check(size_type i, const std::string &msg) const;
    };
    
    StrBlob::StrBlob() : data(std::make_shared<std::vector<std::string>>()) {}
    StrBlob::StrBlob(std::initializer_list<std::string> il) : data(std::make_shared<std::vector<std::string>>(il)) {}
    
    void StrBlob::check(size_type i, const std::string &msg) const
    {
    	if (i >= data->size())
    		throw std::out_of_range(msg);
    }
    
    std::string& StrBlob::front()
    {
    	check(0, "front on empty StrBlob");
    	return data->front();
    }
    
    std::string& StrBlob::back()
    {
    	check(0, "back on empty StrBlob");
    	return data->back();
    }
    
    const std::string& StrBlob::front() const
    {
    	check(0, "front on empty StrBlob");
    	return data->front();
    }
    
    const std::string& StrBlob::back() const
    {
    	check(0, "back on empty StrBlob");
    	return data->back();
    }
    
    void StrBlob::pop_back()
    {
    	check(0, "pop_back on empty StrBlob");
    	data->pop_back();
    }
    

    练习12.6

    #include<vector>
    #include<iostream>
    #include<string>
    
    using namespace std;
    
    vector<int> *create_vi() {
    	return new std::vector<int>;
    }
    
    void push_vi(vector<int> *p) {
    	int i;
    	while (cin >> i) {
    		p->push_back(i);
    	}
    }
    
    void print_vi(vector<int> *p) {
    	for (const auto i : (*p)) {
    		cout << i << " ";
    	}
    	cout << endl;
    }
    
    int main() {
    	auto p = create_vi();
    	push_vi(p);
    	print_vi(p);
    	delete(p);
    	system("pause");
    	return 0;
    }
    

    练习12.7

    #include<vector>
    #include<iostream>
    #include<string>
    #include<memory>
    
    using namespace std;
    
    shared_ptr<vector<int>> create_vi() {
    	return make_shared<vector<int>>();
    }
    
    void push_vi(shared_ptr<vector<int>> p) {
    	int i;
    	while (cin >> i) {
    		p->push_back(i);
    	}
    }
    
    void print_vi(shared_ptr<vector<int>> p) {
    	for (const auto i : (*p)) {
    		cout << i << " ";
    	}
    	cout << endl;
    }
    
    int main() {
    	auto p = create_vi();
    	push_vi(p);
    	print_vi(p);
    	system("pause");
    	return 0;
    }
    

    练习12.8
    有,p的类型被强制转换为bool值,并且new的内存没有delete。

    练习12.9
    r=q后r所指的内存没有释放,再使用p指针会出错。

    练习12.10
    正确

    练习12.11
    离开process时,p指向的内存会被释放,再使用p指针会出现错误。

    练习12.12
    a.合法,将智能指针赋值给process
    b.不合法,shared_ptr初始化内置指针时需要使用直接初始化的形式。
    c.不合法,shared_ptr初始化内置指针时需要使用直接初始化的形式。
    d.合法。

    练习12.13
    sp和p指向同一个内存,释放了p所指的内存后,再使用sp调用对象可能会出错。

    练习12.14

    #include<iostream>
    #include<memory>
    #include<string>
    
    using namespace std;
    
    struct destination {
    	string des;
    	destination(string des_) :des(des_) {}
    };
    
    struct connection{
    	string conn;
    	connection(string conn_) :conn(conn_) {}
    };
    
    connection connect(destination *des_) {
    	cout << "connect to: " << des_->des << endl;
    	return connection(des_->des);
    }
    
    void disconnect(connection conn_) {
    	cout << "disconnect " << conn_.conn << endl;
    }
    
    void end_connection(connection *p) { disconnect(*p); }
    
    void f(destination &d) {
    	connection c = connect(&d);
    	shared_ptr<connection> p(&c, end_connection);  //p接管了内置指针&c所指向的对象的所有权
    	cout << "connecting now(" << p.use_count() << ")" << endl;
    }
    
    int main() {
    	destination des("aa");
    	f(des);
    
    	system("pause");
    	return 0;
    }
    

    练习12.15

    #include<iostream>
    #include<memory>
    #include<string>
    
    using namespace std;
    
    struct destination {
    	string des;
    	destination(string des_) :des(des_) {}
    };
    
    struct connection{
    	string conn;
    	connection(string conn_) :conn(conn_) {}
    };
    
    connection connect(destination *des_) {
    	cout << "connect to: " << des_->des << endl;
    	return connection(des_->des);
    }
    
    void disconnect(connection conn_) {
    	cout << "disconnect " << conn_.conn << endl;
    }
    
    void end_connection(connection *p) { disconnect(*p); }
    
    void f(destination &d) {
    	connection c = connect(&d);
    	shared_ptr<connection> p(&c, [](connection *p) {disconnect(*p);});  //p接管了内置指针&c所指向的对象的所有权
    	cout << "connecting now(" << p.use_count() << ")" << endl;
    }
    
    int main() {
    	destination des("aa");
    	f(des);
    
    	system("pause");
    	return 0;
    }
    

    练习12.16

    #include<iostream>
    #include<memory>
    using namespace std;
    
    int main() {
    	unique_ptr<string> p1(new string("Stegosaurus"));
    	//unique_ptr<string> p2 = p1;
    	//unique_ptr<string> p3(p1);
    	system("pause");
    	return 0;
    }
    

    尝试引用已删除的函数

    练习12.17

    (a)不合法,ix不是new返回的指针

    (b)不合法,pi不是new返回的指针

    (c)合法

    (d)不合法,&ix不是new返回的指针

    (e)合法

    (f)不合法,必须使用new返回的指针进行初始化,赋值和拷贝的操作也不包含get()方法

    练习12.18

    release()函数的作用就是放弃对指针指向对象的控制权,但shared_ptr是多对一的关系,其他的智能指针仍然可以删除这个对象,所以这个函数的话对shared_ptr 没意义

    练习12.19

    class StrBlob
    {
    public:
    	friend class StrBlobPtr;//声明friend
    	StrBlobPtr begin();
    	StrBlobPtr end();
    	StrBlob();//默认构造函数
    	StrBlob(initializer_list<string> il):data(make_shared<vector<string>>(il)){}
    	StrBlob(string il):data(make_shared<vector<string>> (il)){}
    	typedef vector<string>::size_type size_type;//定义类型别名,方便使用
     
    	//定义函数,返回大小
    	size_type size() const
    	{
    		return data->size();
    	}
    	//判断vector<string>是否为空
    	bool empty()
    	{
    		return data->empty();
    	}
    	//向vector<string>中加入元素
    	void pushback(const string &s)
    	{
    		data->push_back(s);
    	}
    	//访问函数,应首先调用check()
    	string& front()
    	{
    		check(0,"front on empty StrBlob");
    		return data->front();
    	}
    	string& back()
    	{
    		check(0,"back on empty StrBlob");
    		return data->back();
    	}
    	void popback()
    	{
    		check(0,"pop_back on empty StrBlob");
    		data->pop_back();
    	}
     
    private:
    	shared_ptr<vector<string>> data;//指向vector<string>的智能指针
    	void check(size_type i,const string &msg) const//若访问元素的大小大于data的size,输出错误信息
    	{
    		if (i > data->size())
    		{
    			throw out_of_range(msg);//抛出该out_of_range异常,表示不在范围之内
    		}
    	}
    };
     
    class StrBlobPtr
    {
    public:
    	StrBlobPtr():curr(0){}//构造函数,将curr设定为0
    	StrBlobPtr(StrBlob &a, size_t sz = 0):wptr(a.data),curr(sz){}//构造函数,将StrBlob的智能指针与此类中的weak_ptr绑定
    	string& deref() const
    	{
    		auto p =check(curr,"deference past end");
    		return (*p)[curr];
    	}
    	StrBlobPtr& incr()
    	{
    		auto p =check(curr,"deference past end");
    		++curr;
    		return *this;
    	}
    private:
    	shared_ptr<vector<string>> check(size_t i,const string& msg) const//检查函数,返回一个vector<string>的智能指针
    	{
    		auto ret = wptr.lock();//检查对象是否还存在
    		if(!ret)
    		{
    			throw runtime_error("未绑定");
    		}
    		if (i >= ret->size())
    		{
    			throw out_of_range(msg);
    		}
    		return ret;
    	}
    	weak_ptr<vector<string>> wptr;//定义弱智能指针
    	size_t curr;//设立游标,表示下标
     
    };
     
    StrBlobPtr StrBlob::begin()
    {
    	return StrBlobPtr(*this);
    }
    StrBlobPtr StrBlob::end()
    {
    	return StrBlobPtr(*this, data->size());
    }
    

    练习12.23

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<string>
    using namespace std;
    
    int main() {
    	const char a[] = "aaa";
    	const char b[] = "bbb";
    	char *ans = new char[strlen(a) + strlen(b) + 1];
    	strcpy(ans, a);
    	strcat(ans, b);
    	cout << string(ans) << endl;
    	delete[] ans;
    	system("pause");
    	return 0;
    }
    
    #include<iostream>
    #include<string>
    
    using namespace std;
    
    int main() {
    	const string a = "aaa";
    	const string b = "bbb";
    	cout << a + b << endl;
    	system("pause");
    	return 0;
    }
    

    练习12.24

    #define _CRT_SECURE_NO_WARNINGS
    #include<iostream>
    #include<string>
    
    using namespace std;
    
    int main() {
    	string s;
    	cin >> s;
    	char *t = new char[s.size() + 1];
    	strcpy(t, s.c_str());
    	cout << t << endl;
    	delete[] t;
    	system("pause");
    	return 0;
    }
    

    练习12.25

    delete[] pa;
    

    练习12.26

    #include<iostream>
    #include<memory>
    #include<string>	
    
    using namespace std;
    int main() {
    	allocator<string> alloc;
    	auto const p = alloc.allocate(10);
    	string s;
    	auto q = p;
    	while (cin >> s && q != p + 10) {
    		alloc.construct(q++, s);
    	}
    	while (q!=p)
    	{
    		alloc.destroy(--q);
    	}
    	alloc.deallocate(p, 100);
    
    	system("pause");
    	return 0;
    }
    
  • 相关阅读:
    JDK中的主要包
    package

    参数传值机制
    静态初始化块
    static 关键字
    this关键字
    开发中容易造成内存泄露的操作
    通用的分代垃圾回收机制
    JVM调优和Full GC
  • 原文地址:https://www.cnblogs.com/Mered1th/p/10585550.html
Copyright © 2011-2022 走看看