Проблема в том, что вы выделяете только 1 TCHAR
, а затем пишете после конца выделенного блока памяти.Ваш код имеет неопределенное поведение .
Вам нужно использовать new _TCHAR[...]
вместо new _TCHAR()
.
Вы также не обрабатываете случай, когда обратные слэши не обнаружены.В этом случае lastBackslash
равно 0, хотя 1-й символ не является обратной косой чертой.Вы не проверяете эту возможность.И поскольку ваш цикл использует <=
вместо <
, он будет копировать этот 1-й символ, когда это не должно быть.
Вместо этого попробуйте что-то более похожее на это:
const size_t c_invalid_index = (size_t) -1;
_TCHAR* GetDirectoryFromPath(const _TCHAR* path)
{
size_t lastBackslash = c_invalid_index;
size_t size = _tcslen(path);
for (size_t i = 0; i < size; ++i)
{
if (path[i] == _T('\\'))
{
lastBackslash = i;
}
}
if (lastBackslash == c_invalid_index)
return NULL;
_TCHAR* dirPath = new _TCHAR[lastBackslash + 2];
for (size_t i = 0; i <= lastBackslash; ++i)
{
dirPath[i] = path[i];
}
dirPath[lastBackslash + 1] = _T('\0');
return dirPath;
}
В качестве альтернативы:
_TCHAR* GetDirectoryFromPath(const _TCHAR* path)
{
const _TCHAR *lastBackslash = NULL;
size_t size = _tcslen(path);
for (size_t i = 0; i < size; ++i)
{
if (path[i] == _T('\\'))
{
lastBackslash = &path[i];
}
}
if (!lastBackslash)
return NULL;
size = (lastBackslash - path) + 1;
_TCHAR* dirPath = new _TCHAR[size + 1];
for (size_t i = 0; i < size; ++i)
{
dirPath[i] = path[i];
}
dirPath[size] = _T('\0');
return dirPath;
}
Тем не менее, вы действительно не должны использовать необработанные строковые указатели, подобные этому.Вместо этого было бы гораздо безопаснее использовать std::basic_string<_TCHAR>
(если не std::string
или std::wstring
, или std::u16string
или std::u32string
в C ++ 11 и более поздних версиях), например:
#include <string>
typedef std::basic_string<_TCHAR> tstring;
...
tstring GetDirectoryFromPath(const tstring &path)
{
tstring::size_type pos = path.find_last_of(_T('\\'));
if (pos == tstring::npos)
return tstring();
return path.substr(0, pos+1);
}