我的程序在尝试复制未通过NULL终止符('\ 0')结束的字符数组时间歇性崩溃。
class CMenuButton {
TCHAR m_szNode[32];
CMenuButton() {
memset(m_szNode, '\0', sizeof(m_szNode));
}
};
int main() {
....
CString szTemp = ((CMenuButton*)pButton)->m_szNode; // sometime it crashes here
...
return 0;
}
我怀疑有人没有复制好以“\ 0”结尾的字符,结果如下:
Stack
m_szNode $%#^&!&!&!*@*#&!(*@(!*@@&#&*&@@!^&*&#(*!@*((*&*SDFKJSHDF*(&(*&(()(**
你能告诉我发生了什么,我该怎么做才能防止复制野指针?非常感谢帮助!
我想在复制之前我无法检查字符数组是否为NULL ...
答案 0 :(得分:3)
我怀疑你的真正问题可能是pButton
是一个坏指针,所以先检查一下。
唯一可以100%确定指针正确并且指向正确大小/已分配对象的方法是永远不要使用你没有创建的指针,也不要接受/返回指针。你会使用cookies,然后在某种cookie中查找你的指针 - >指针查找(例如哈希表)。基本上,不要相信用户输入。
如果您更关心发现错误,并且对缓冲区溢出攻击等问题的安全性较低,那么您可以采取不那么激进的方法。在函数签名中,当前指向数组的指针,添加一个size参数。 E.g:
void someFunction(char* someString);
变为
void someFunction(char* someString, size_t size_of_buffer);
此外,强制终止函数中的数组/字符串。如果你到达终点,并且它不是以null结尾,则截断它。
这样做可以在调用缓冲区时提供缓冲区的大小,而不是在调用它们之前在所有数组上调用strlen(或等效的)。
这类似于Microsoft创建的“安全字符串函数”所采用的方法(其中一些是为标准化而提出的)。不确定这是否是完美链接,但您可以谷歌获取其他链接:
http://msdn.microsoft.com/en-us/library/ff565508(VS.85).aspx
答案 1 :(得分:2)
有两种可能性:
pButton
并不像您认为的那样指向CMenuButton
,并且演员阵容导致未定义的行为。m_szNode
的代码不正确,超出了32个字符的给定大小。由于您没有向我们展示任何一段代码,因此很难看出错误。您初始化m_szNode
看起来没问题。
有没有理由没有为m_szNode
选择CString?
答案 2 :(得分:0)
我的方法是让m_szNode
成为CMenuButton
中的私有成员,并明确地NULL
- 在mutator方法中终止它。
class CMenuButton {
private:
TCHAR m_szNode[32];
public:
void set_szNode( TCHAR x ) {
// set m_szNode appropriately
m_szNode[ 31 ] = 0;
}
};