11.2节中,见识到了c++内存管理的险恶,如何解决

Hard Copy

出现原因:多个对象同时指向一块内存空间。
解决方案:所有的对象都拥有自己的内存数据。

11.2中的例子中,错误的罪魁祸首就是C++默认提供的Copy Constructor,它把指针直接赋值了。

  • Provide a user-defined copy constructor. ```cpp MyString::MyString(const MyString & ms) { this->buf_len = 0; this->characters = NULL; create(ms.buf_len, ms.characters); }
  1. - `create()` release the current memory and **allocate a new one.**
  2. - **会显示放当然内存,然后重新申请一个新的内存空间。**
  3. - `**t**his->characters` will not point to `ms.characters`.
  4. - 保证了当前对象的指针不跟参数的指针相同
  5. - **It's a hard copy!**
  6. 第二个错误产生的原因:赋值运算符出现了问题<br />默认的运算符重载做了两个变量的复制,我们可以自定义运算符重载函数,
  7. - Provide a user-defined copy assignment
  8. - 使用create去申请内存,使得每个对象都有自己的内存,不在共享
  9. ```cpp
  10. #pragma once
  11. #include <iostream>
  12. #include <cstring>
  13. class MyString
  14. {
  15. private:
  16. int buf_len;
  17. char *characters;
  18. public:
  19. MyString(int buf_len = 64, const char *data = NULL)
  20. {
  21. std::cout << "Constructor(int, char*)" << std::endl;
  22. this->buf_len = 0;
  23. this->characters = NULL;
  24. create(buf_len, data);
  25. }
  26. MyString(const MyString &ms)
  27. {
  28. std::cout << "Constructor(MyString&)" << std::endl;
  29. this->buf_len = 0;
  30. this->characters = NULL;
  31. create(ms.buf_len, ms.characters);
  32. }
  33. ~MyString()
  34. {
  35. release();
  36. }
  37. MyString &operator=(const MyString &ms)
  38. {
  39. create(ms.buf_len, ms.characters);
  40. return *this;
  41. }
  42. bool create(int buf_len, const char *data)
  43. {
  44. release();
  45. this->buf_len = buf_len;
  46. if (this->buf_len != 0)
  47. {
  48. this->characters = new char[this->buf_len]{};
  49. }
  50. if (data)
  51. strncpy(this->characters, data, this->buf_len);
  52. return true;
  53. }
  54. bool release()
  55. {
  56. this->buf_len = 0;
  57. if (this->characters != NULL)
  58. {
  59. delete[] this->characters;
  60. this->characters = NULL;
  61. }
  62. return 0;
  63. }
  64. friend std::ostream &operator<<(std::ostream &os, const MyString &ms)
  65. {
  66. os << "buf_len = " << ms.buf_len;
  67. os << ", characters = " << static_cast<void *>(ms.characters);
  68. os << " [" << ms.characters << "]";
  69. return os;
  70. }
  71. };