由于奇怪的问题而将对象分配给自身 我用C++标准库在C++中使用一个字符串类。< /P>
这个类相当简单:构造函数获取一个字符串并使用malloc将它所需的内存量分配到一个char指针中,构造函数释放它,如果需要,它重新分配。其余的是读/写功能,不需要更多或更少的内存 我做的一个函数将内容更改为小写,将其放入一个新对象(在堆栈上创建)并返回。然而,我试着按照以下思路做一些事情:str=str.toLower();不用说,它失败得很惨 每隔一次我启动exe时,它就会崩溃。在无意识地搜索了几个小时后,我制作了一些消息框,告诉我什么时候分配和释放了一些东西,以及它是什么。事实证明,出于某种原因,它一直在从任何地方分配和取消分配各种项目。我假设这是由于一个悬空的指针,所以我修复了它 然而,它仍然在分配和释放大量的东西,并且崩溃 以下是相关代码: 构造函数/析构函数:由于奇怪的问题而将对象分配给自身 我用C++标准库在C++中使用一个字符串类。< /P>,c++,memory,memory-management,C++,Memory,Memory Management,这个类相当简单:构造函数获取一个字符串并使用malloc将它所需的内存量分配到一个char指针中,构造函数释放它,如果需要,它重新分配。其余的是读/写功能,不需要更多或更少的内存 我做的一个函数将内容更改为小写,将其放入一个新对象(在堆栈上创建)并返回。然而,我试着按照以下思路做一些事情:str=str.toLower();不用说,它失败得很惨 每隔一次我启动exe时,它就会崩溃。在无意识地搜索了几个小时后,我制作了一些消息框,告诉我什么时候分配和释放了一些东西,以及它是什么。事实证明,出于某种
String::String(const char* str)
{
data = nullptr;
MessageBox(NULL, str, "Allocating", MB_OK);
//getSizeOfCharArray does not include the NULL at the end, so add 1
data_size = getSizeOfCharArray(str)+1;
data = (char*)malloc(sizeof(char)*data_size);
strcpy(data, str);
}
String::~String()
{
MessageBox(NULL, data, "Freeing", MB_OK);
if (data != nullptr)
{
free(data);
data = nullptr;
}
}
小写函数:
String String::toLower()
{
char* lower = (char*)malloc(sizeof(char)*data_size);
for (int i = 0; i < data_size; i++)
{
lower[i] = tolower(data[i]);
}
String temp(lower);
free(lower);
return temp;
}
我有其他对话框文本,但显然“/z”是一个常见的文本
就这样持续了一段时间
什么可能导致这种情况?如果没有
操作符=
重载,将执行浅拷贝而不是深拷贝。我认为如果您可以粘贴操作符=
您尝试的内容没有意义,但是可以
C++中,如果没有显式声明类赋值运算符重载,则隐式创建一个为其执行浅拷贝的。复制构造函数、默认构造函数和析构函数也是如此。任何其他用户定义构造函数的存在都将禁止隐式为您创建默认构造函数,因此,如果您仍然希望它存在于接受
常量char*
的构造函数之外,则必须显式声明它
当在课堂上使用动态记忆时,我们有我们喜欢称之为3法则或邪恶三部曲的东西。这意味着您必须显式编写(1)析构函数,否则可能会导致内存泄漏,必须显式编写或删除(2)复制构造函数和(3)复制赋值运算符,否则可能会导致多个实例共享同一内存,这至少会导致同一内存被多次删除,如果不是其他不希望的行为的话
由于您没有发布字符串类的外观,下面是您可能需要执行的示例:
class String
{
public:
String(); // Default constructor
String(const char* s); // Custom constructor
String(const String& rhs); // Copy constructor
String& operator=(const String& rhs); // Copy assignment operator
~String(); // Destructor
String(String&& rhs); // (Optional) Move constructor
String& operator=(String&& rhs); // (Optional) Move assignment
// TODO: Other public functions
private:
char* m_string;
};
String::String() : m_string(nullptr)
{
}
String::String(const char* s)
{
// TODO: Copy the string into m_string
}
String::String(const String& rhs)
{
// TODO: Deep copy
}
String& String::operator=(const String& rhs)
{
if(this != &rhs)
{
// TODO: Deep copy
}
return *this;
}
String::~String()
{
delete m_string;
}
而且,这让我很烦,你不需要使用Windows消息框作为记录器。只需将日志消息输出到控制台或日志文件。您的字符串类需要一个工作的、用户定义的复制构造函数和赋值运算符 由于函数
toLower
按值返回一个String
,因此对象需要正确的复制语义,因为调用的String
类的operator=
如果没有用户定义的复制构造函数,则将使用编译器的默认复制构造函数。默认版本只将指针值复制到新的字符串
对象——它不知道如何调用malloc
,然后调用strcpy
复制数据。这是你自己写的
String::String(const String& str) : data_size(str.data_size),
data(malloc(str.data_size))
{ strcpy(data, str.data); }
还需要完成赋值运算符。它应该是这样的:
#include <algorithm>
//...
String& operator=(String str)
{
std::swap(data, str.data);
std::swap(data_size, str.data_size);
return *this;
}
#包括
<>也可以,对于C++,你使用<代码>新[] < /COD>和<代码>删除[]/COD>而不是<代码> Malc 和<代码>免费< /代码>。<为什么要写代码> C >代码>语言标签?我添加它是因为它部分地涉及C标准库。为什么要给自己分配一个对象?我在C++中使用C标准库来处理一个字符串类?什么。此外,您可能希望习惯于<代码>新< /COD>和<代码>删除< /代码>,而不是<代码> Malc C++ >代码>和<代码>免费>代码>。
#include <algorithm>
//...
String& operator=(String str)
{
std::swap(data, str.data);
std::swap(data_size, str.data_size);
return *this;
}