【发布时间】:2016-12-29 23:25:58
【问题描述】:
我在 c++ 中做一个 dll,第二次调用函数时出现此错误:
调试断言失败表达式:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
我做了一些研究,这似乎发生在我 delete 一个我没有 new 的对象时
这是我认为失败的代码
class tFont
{
public:
tFont(char chars[], __int64 cods[], int count);
~tFont();
int fontCount = 0;
char* characters = NULL;
long long* codes = NULL;
std::vector<std::pair<char,long long>> exceptions;
char getCharacter(long long code);
};
tFont::tFont(char chars[], long long cods[], int count)
{
characters = new char[count];
codes = new long long[count];
fontCount = count;
for (int i = 0; i < count; i++)
{
characters[i] = chars[i];
codes[i] = cods[i];
}
}
tFont::~tFont()
{
delete[] characters;
delete[] codes;
}
Visual Studio 在出错后停止在delete[] characters;。
我尝试了这个没有任何运气
if (characters != NULL)
{
delete[] characters;
}
if (codes != NULL)
{
delete[] codes;
}
我只创建这个类的一个实例作为静态对象
tFont* getCapFont()
{
static tFont *capFont = NULL;
if (capFont == NULL)
{
char characters[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
long long codes[] = { 241136, 441, 183861, 102321, 45836, 5955, 19305, 7871, 220321, 102286 };
int fontCount = 10;
capFont = new tFont(characters, codes, fontCount);
pair<char, long long> e;
e.first = '0';
e.second = 24045;
capFont->exceptions.push_back(e);
}
return capFont;
}
为什么即使我从不调用析构函数delete capFont
谢谢!
Edit2:我按照'jarmod'所说的那样做,抛出错误的那一刻是这个函数结束的时候
void analysis::singleLineTextReader(tImage img, char result[], tFont font)
我说这是我第二次调用函数时发生的,可能singleLineTextReader结束时调用了其参数font的析构函数?上面描述的静态对象是哪个
【问题讨论】:
-
只是猜测,但请参阅Rule of 3/5/0。我还建议查看
std::vector、std::unique_ptr和std::shared_ptr。 -
将一些调试打印语句添加到各种方法中,看看发生了什么。可能不是你想的那样。此外,在调用 delete 之前没有绝对需要测试 NULL,但是在调用 delete 之后将指针设为 null 是一个很好的做法(并且可以选择在删除之前断言它不是 null,以捕获您不小心出现的编码错误双删除指针)。
-
Edit2 后:
singleLineTextReader获取其参数按值,这意味着它创建了字体的副本。该副本将包含在构造函数中创建的指针的副本,这些将在析构函数中被删除。之后,原始字体对象将包含悬空指针。 -
“我删除了一个我没有新建的对象”,你为什么要这样做?
-
@BoPersson - Captain Obvlious 啊,当我通过复制传递参数时,它会自动调用类的复制构造函数,谢谢!
标签: c++