无法安全删除LPTSTR分配

时间:2016-11-14 15:45:32

标签: c++ winapi

考虑:

CCustomDateTime::CCustomDateTime()
{
    LPTSTR result = new TCHAR[1024];
    time_t _currentTime_t = time(0);
    tm now;

    localtime_s(&now, &_currentTime_t);
    _tasctime_s(result, _tcslen(result), &now);

    _currentTime = result;
    delete[] result; // Error occurs here
}


CCustomDateTime::~CCustomDateTime()
{

}

__int64 CCustomDateTime::CurrentTimeAsInt64()
{
    return _currentTime_t;
}

LPTSTR CCustomDateTime::CurrentTimeAsString()
{
    return _currentTime;
}

我无法找到delete[]上最安全的地方result

如果忽略delete[],一切都很好,否则会发生错误:

  

在行删除[]

时检测到HEAP CORUPTION

3 个答案:

答案 0 :(得分:2)

_tcslen(result)没有按照你的想法行事 改变

_tasctime_s(result, _tcslen(result), &now);  

_tasctime_s(result, 1024, &now);

答案 1 :(得分:1)

我可以看到您的代码存在一些问题:

  1. 您不检查任何函数调用是否有错误。不要忽略返回值。用它来检查错误。
  2. _tasctime_s的第二个参数是提供的缓冲区中的元素数。换句话说,1024。但是你传递_tcslen(result),它是以null结尾的字符串的长度。这不仅是错误的值,而且result在此时未初始化,因此您的代码具有未定义的行为。
  3. 您为_currentTime分配值,然后立即删除该内存。所以,_currentTime是一个陈旧的指针。任何从该内存中读取的尝试都是更加未定义的行为。
  4. 我不想告诉你你的代码应该是什么,因为你只给了我们一个小窗口,了解你想要实现的目标。动态分配固定长度的数组似乎毫无意义。您也可以使用自动分配的存储空间。当然,如果你确实想要将内存返回给调用者,那么动态分配是有意义的,但在这种情况下,调用者肯定会负责调用delete[]。由于这段代码显然是C ++,我不得不想知道你为什么要使用原始内存分配。为什么不使用std::string等标准库类?

    查看对问题的更新,您可以在类的析构函数中释放内存。就个人而言,我建议学习标准库类,这将大大简化您的代码。

答案 2 :(得分:1)

_tcslen映射到strlenwcslen,具体取决于您是分别使用ANSI还是Unicode。

这两个函数都返回字符串 length ,而不是 buffer size 。换句话说,它们获取指向字符串的第一个字符的指针,并不断递增指针以搜索空终止符。

在未初始化的缓冲区上调用这些函数是未定义的行为,因为指针很可能会从数组边界和其他地方递增到进程的内存中。