目录
1.使用char类型数组表达字符串的缺陷
完整代码
2.解决方案
a.Hard Copy
b.soft copy(OpenCV Mat/CvMat)
使用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;
}
程序运行出错
先构造的后析构
出错原因:
先调用str3的析构函数。(析构函数的调用顺序与构造函数的调用顺序相反。)
深圳内存释放
str2再次释放深圳报错,释放的内存没有被申请。
内存泄露:64个字节的内存没人保存。没人知道他的地址。
所有对象都要指向自己的内存。拥有自己的内存
原因:多个对象指向同一块内存,
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;
}
S1:缺点:
1.每次创建对象都要申请内存。
2.申请释放特别频繁?
3.如果每次申请内存比较大的话,比较耗时。效率比较低。内存利用率比较低。
OpenCV cvMat结构体
refcount指向一块数据。存储被多少个对象引用。这个矩阵在申请数据的时候会多申请4个字节放在前面。用来存储这个数据被多少个对象引用,赋值的时候加一,释放的时候减一。
data是一个union联合体
这5个指针指向同样一块内存。他们的地址是完全相同的。可以实现不同数据类型的使用。
Mat类(更加精简,使用起来更加安全。)多个对象共享同一块内存的方案。
u是用来存储引用的,data被多少对象引用
首先判断引用是不是他自己。
data=m.data
两个对象共享了同一块数据。
复制构造函数
当前对象的data的这个指针指向参数m的指针,共享一块数据