简单赋值时内存分配错误
Memory allocation error when simply assigning values
为了从给定路径获取父目录,我有以下代码。
注意:size_t 是 typedef for unsigned int.
/****************************************************
This function takes a full path to a file, and returns
the directory path by returning the string up to the last backslash.
Author: Aashish Bharadwaj
*****************************************************/
_TCHAR* GetDirectoryFromPath(const _TCHAR* path)
{
size_t size = _tcslen(path);
size_t lastBackslash = 0;
for (size_t i = 0; i < size; i++)
{
if (path[i] == '\')
{
lastBackslash = i;
}
}
_TCHAR* dirPath = new _TCHAR();
size_t i;
for (i = 0; i <= lastBackslash; i++)
{
dirPath[i] = path[i];
}
dirPath[i + 1] = '[=10=]'; //THIS IS VERY NECESSARY! Otherwise, a bunch of garbage is appended to the character array sometimes.
return dirPath;
}
问题是 有时 它会在 returns.
我想知道是否有人知道这是什么以及为什么会这样。
问题是您只分配了 1 TCHAR
,然后您正在写入已分配的内存块的末尾。您的代码有 未定义的行为。
您需要使用 new _TCHAR[...]
而不是 new _TCHAR()
。
您也没有处理没有找到反斜杠的情况。在这种情况下,即使第一个字符不是反斜杠,lastBackslash
也是 0。您没有检查这种可能性。因为你的循环使用 <=
而不是 <
,它最终会在不应该复制第一个字符的时候复制它。
尝试更像这样的东西:
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('[=10=]');
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('[=11=]');
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);
}
为了从给定路径获取父目录,我有以下代码。 注意:size_t 是 typedef for unsigned int.
/****************************************************
This function takes a full path to a file, and returns
the directory path by returning the string up to the last backslash.
Author: Aashish Bharadwaj
*****************************************************/
_TCHAR* GetDirectoryFromPath(const _TCHAR* path)
{
size_t size = _tcslen(path);
size_t lastBackslash = 0;
for (size_t i = 0; i < size; i++)
{
if (path[i] == '\')
{
lastBackslash = i;
}
}
_TCHAR* dirPath = new _TCHAR();
size_t i;
for (i = 0; i <= lastBackslash; i++)
{
dirPath[i] = path[i];
}
dirPath[i + 1] = '[=10=]'; //THIS IS VERY NECESSARY! Otherwise, a bunch of garbage is appended to the character array sometimes.
return dirPath;
}
问题是 有时 它会在 returns.
我想知道是否有人知道这是什么以及为什么会这样。
问题是您只分配了 1 TCHAR
,然后您正在写入已分配的内存块的末尾。您的代码有 未定义的行为。
您需要使用 new _TCHAR[...]
而不是 new _TCHAR()
。
您也没有处理没有找到反斜杠的情况。在这种情况下,即使第一个字符不是反斜杠,lastBackslash
也是 0。您没有检查这种可能性。因为你的循环使用 <=
而不是 <
,它最终会在不应该复制第一个字符的时候复制它。
尝试更像这样的东西:
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('[=10=]');
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('[=11=]');
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);
}