假设我有一个班级
class person
{
char* name;
public:
void setname(const char*);
};
void person::setname(const char* p)
{
name=new char[strlen(p)];
strcpy(name,p);
name[strlen(p)]='\0';
}
我的问题是关于这条线 name = new char [strlen(p)]; 假设p指针指向字符串,即“zia”,现在strlen(p)将返回3,这意味着我们有一个包含4个字符的数组,即char [3]现在我将字符串复制到名称中,在第4个位置,我把空字符,这有什么问题?????
答案 0 :(得分:5)
你说:
我们有一个4个字符的数组,即 炭[3]
令人惊讶的是,char [3]是三个字符的数组,而不是四个!
答案 1 :(得分:3)
你必须为零终结符再分配一个char:
name = new char[strlen(p) + 1];
答案 2 :(得分:2)
问题是
delete[] name;
,因此每次用户调用setname()
时,您都会泄漏数组。'\0'
元素分配的额外strlen(p)+1
。答案 3 :(得分:2)
您需要为\ 0字符分配一个内存位置,否则在执行此操作时name[strlen(p)]='\0';
会出现分段错误。基本上做new char[strlen(p) + 1]
。
答案 4 :(得分:2)
你应该分配strlen(p)+1个字符:
name = new char[strlen(p)+1];
答案 5 :(得分:2)
你出错的地方在这里:
现在strlen(p)将返回3表示我们有一个包含4个字符的数组,即char [3]
4个字符的数组是char[4]
;如果动态分配,则必须将4传递给operator new
,或者通常为:
name=new char[strlen(p)+1];
答案 6 :(得分:1)
void person::setname(const char* p)
{
name=new char[strlen(p) + 1]; // make a room to have null character
strcpy(name,p);
name[strlen(p)]='\0';
}
数组索引从0开始,因此size = 5的数组的最大索引是arr [4]。
答案 7 :(得分:1)
很多人都提到了解决你遇到的直接问题的方法。在这样做的时候,他们差点让你感到不舒服。除非你有真的这样做的理由,否则你应该做的是将名称定义为std::string
,并使用其赋值运算符来正确处理作业。
如果你有一个非常好的理由避免使用std::string
,那么你应该设计一个你自己的字符串类,然后使用它。至少在我看来,以你的方式编写代码,动态分配和strcpy
到处都是一个糟糕的主意。即使在最好的情况下,也很难阅读,容易出现大量愚蠢的错误,并且基本上不可能使任何接近异常的安全。