c++ - 如何在 C++ 异常类析构函数中释放变量
问题描述
我正在定义一个新的 C++ 类,它的what
方法返回一个char*
类型,该类型具有作为构造函数传递的整数值。
最初我使用string
类并从what
.
然后我尝试char*
在以下代码中使用类型:
/* Define the exception here */
class BadLengthException: public exception
{
public:
BadLengthException(int strLength)
{
strLen = strLength;
res = (char*)malloc(strLength+1);
int resultSize = sprintf(res, "%d", strLen);
}
~BadLengthException() throw()
{
free(res);
}
virtual const char* what() const throw()
{
return res;
}
private:
int strLen;
char* res;
};
但我在释放malloc
分配的变量时遇到问题:它给出了这个异常:
pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
那为什么呢?我应该在哪里以及如何释放 Exception 类中的动态分配变量?
编辑
这是一个最小的工作完整示例。该程序将要求用户输入。第一个是一个数字,指定以下输入的数量。其他输入将是字符串。如果字符串短于 5,将引发上述异常。
只需输入:1
然后Me
例如
#include <iostream>
#include <string>
#include <sstream>
#include <exception>
using namespace std;
/* Define the exception here */
class BadLengthException: public exception
{
public:
BadLengthException(int strLength)
{
strLen = strLength;
res = (char*)malloc(strLength+1);
int resultSize = sprintf(res, "%d", strLen);
}
~BadLengthException() throw()
{
free(res);
}
virtual const char* what() const throw()
{
return res;
}
private:
int strLen;
char* res;
};
bool checkUsername(string username) {
bool isValid = true;
int n = username.length();
if(n < 5) {
throw BadLengthException(n);
}
for(int i = 0; i < n-1; i++) {
if(username[i] == 'w' && username[i+1] == 'w') {
isValid = false;
}
}
return isValid;
}
int main() {
int T; cin >> T;
while(T--) {
string username;
cin >> username;
try {
bool isValid = checkUsername(username);
if(isValid) {
cout << "Valid" << '\n';
} else {
cout << "Invalid" << '\n';
}
} catch (BadLengthException e) {
cout << "Too short: " << e.what() << '\n';
}
}
return 0;
}
编辑 2
使用字符串的原始类如下:这个确实有效
class BadLengthException: public exception
{
public:
BadLengthException(int strLength)
{
res = to_string(strLength);
}
virtual const char* what() const throw()
{
return res.c_str();
}
private:
string res;
};
解决方案
这与异常无关。您的课程不能安全复制。
如果您要编写这样的课程,则需要使其遵循三规则。
发生的事情是您的异常对象正在被复制,它复制了指针,因此您释放了两次相同的指针。
但最简单的方法是使用 astd::string
而不是分配自己的内存。
class BadLengthException: public exception
{
public:
BadLengthException(int strLength) : strLen(strLength), res(std::to_string(strLength))
{
}
virtual const char* what() const throw()
{
return res.c_str();
}
private:
int strLen;
std::string res;
};
推荐阅读
- c - 读入数组时出现分段错误
- javascript - 如何为 map 函数中的每次迭代分配一个新的 ref?
- python-3.x - 我无法在 python 生成器中回调
- python - 我正在学习python,但我无法弄清楚这段代码有什么问题?
- android - 我正在尝试使用片段创建 BottomNavigationView,并且我想在主布局中使用片段
- c# - 在上传到 S3 的对象上设置“Content-Disposition”?
- javascript - 如何在两个不同的角度应用程序之间传递数据
- sql - 在 SQL 中,FROM 前面的逗号分隔列表是什么意思?
- angular - Angular:两个输入,一种方式镜像
- javascript - 打字稿/角度:过滤对象数组