C++面向对象4:指针和内存管理

目录

1.使用char类型数组表达字符串的缺陷

完整代码

 2.解决方案

a.Hard Copy

b.soft copy(OpenCV Mat/CvMat)


1.使用char类型数组表达字符串的缺陷

使用char类型数组表达字符串时有缺陷,比如越界等

class MyString//定义一个类包装一下,让这个字符串更加安全
{
    int buf_len;//数组长度
    char * characters;//数组指针
    //动态内存申请:
    不知道字符串有多长,动态内存,需要多少申请多少
  public:
    MyString(int buf_len = 64, const char * data = NULL)
    {
        this->buf_len = 0;
        this->characters = NULL;
        create(buf_len);//申请内存,初始化
    }
    ~MyString()
    {
        delete []this->characters;
    }
    ...
};


完整代码

头文件

#pragma once

#include 
#include 

class MyString
{
  private:
    int buf_len;
    char * characters;
  public:
    MyString(int buf_len = 64, const char * data = NULL)
    {
        std::cout << "Constructor(int, char*)" << std::endl;
        this->buf_len = 0;
        this->characters = NULL;
        create(buf_len, data);
    }
    ~MyString()
    {
        delete []this->characters;
    }
    bool create(int buf_len,  const char * data)
    {
        this->buf_len = buf_len;

        if( this->buf_len != 0)
        {
            this->characters = new char[this->buf_len]{};
        }
        if(data)
            strncpy(this->characters, data, this->buf_len);

        return true;
    }
    friend std::ostream & operator<<(std::ostream & os, const MyString & ms)
    {
        os << "buf_len = " << ms.buf_len;
        os << ", characters = " << static_cast(ms.characters);
        os << " [" << ms.characters << "]";
        return os;
    }
};

主程序

#include 
#include "mystring.hpp"

using namespace std;

// Why memory leak and memory double free?
int main()
{
    MyString str1(10, "Shenzhen");
    cout << "str1: " << str1 << endl;

    MyString str2 = str1; 
    cout << "str2: " << str2 << endl;

    MyString str3;
    cout << "str3: " << str3 << endl;
    str3 = str1;
    cout << "str3:" << str3 << endl;

    return 0;
}

程序运行出错

C++面向对象4:指针和内存管理_第1张图片 C++面向对象4:指针和内存管理_第2张图片

先构造的后析构

出错原因:

先调用str3的析构函数。(析构函数的调用顺序与构造函数的调用顺序相反。)

深圳内存释放

str2再次释放深圳报错,释放的内存没有被申请。

内存泄露:64个字节的内存没人保存。没人知道他的地址。

C++面向对象4:指针和内存管理_第3张图片

 2.解决方案

a.Hard Copy

所有对象都要指向自己的内存。拥有自己的内存

原因:多个对象指向同一块内存,

1.C++提供的默认复制构造函数有问题。

2.赋值运算符出了问题。默认运算符重载,做了两个变量的复制。

头文件

#pragma once
#include 
#include 

class MyString
{
  private:
    int buf_len;
    char * characters;
  public:
    MyString(int buf_len = 64, const char * data = NULL)
    {
        std::cout << "Constructor(int, char*)" << std::endl;
        this->buf_len = 0;
        this->characters = NULL;
        create(buf_len, data);
    }
    MyString(const MyString & ms)//多了个构造函数
    {
        std::cout << "Constructor(MyString&)" << std::endl;
        this->buf_len = 0;
        this->characters = NULL;
        create(ms.buf_len, ms.characters);
    }
    ~MyString()
    {
        release();
    }
    MyString & operator=(const MyString &ms)
    {
        create(ms.buf_len, ms.characters);
        return *this;
    }
    bool create(int buf_len,  const char * data)//做的是值拷贝
    {
        release();//我create之前一定要看看。我有没有内存? 如果有内存,那就把他释放了。

        this->buf_len = buf_len;

        if( this->buf_len != 0)
        {
            this->characters = new char[this->buf_len]{};
        }
        if(data)
            strncpy(this->characters, data, this->buf_len);

        return true;
    }
    bool release()
    {
        this->buf_len = 0;
        if(this->characters!=NULL)
        {
            delete []this->characters;//释放内存。
            this->characters = NULL;//将指针值为0。
        }
        return 0;
    }
    friend std::ostream & operator<<(std::ostream & os, const MyString & ms)
    {
        os << "buf_len = " << ms.buf_len;
        os << ", characters = " << static_cast(ms.characters);
        os << " [" << ms.characters << "]";
        return os;
    }
};

主程序

#include 
#include "mystring.hpp"

using namespace std;

// Why memory leak and memory double free?
int main()
{
    MyString str1(10, "Shenzhen");
    cout << "str1: " << str1 << endl;

    MyString str2 = str1; 
    cout << "str2: " << str2 << endl;

    MyString str3;
    cout << "str3: " << str3 << endl;
    str3 = str1;
    cout << "str3: " << str3 << endl;

    return 0;
}

b.soft copy(OpenCV Mat/CvMat)

S1:缺点:

1.每次创建对象都要申请内存。

2.申请释放特别频繁?

3.如果每次申请内存比较大的话,比较耗时。效率比较低。内存利用率比较低。

OpenCV cvMat结构体

C++面向对象4:指针和内存管理_第4张图片

refcount指向一块数据。存储被多少个对象引用。这个矩阵在申请数据的时候会多申请4个字节放在前面。用来存储这个数据被多少个对象引用,赋值的时候加一,释放的时候减一。

data是一个union联合体

这5个指针指向同样一块内存。他们的地址是完全相同的。可以实现不同数据类型的使用。

Mat类(更加精简,使用起来更加安全。)多个对象共享同一块内存的方案。

C++面向对象4:指针和内存管理_第5张图片

u是用来存储引用的,data被多少对象引用

C++面向对象4:指针和内存管理_第6张图片

首先判断引用是不是他自己。

data=m.data

两个对象共享了同一块数据。

复制构造函数

C++面向对象4:指针和内存管理_第7张图片

当前对象的data的这个指针指向参数m的指针,共享一块数据

C++面向对象4:指针和内存管理_第8张图片

你可能感兴趣的:(C++,c++,opencv)