基本问题c ++,动态内存分配

时间:2010-01-21 11:08:16

标签: c++ oop

假设我有一个班级

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个位置,我把空字符,这有什么问题?????

8 个答案:

答案 0 :(得分:5)

你说:

  我们有一个4个字符的数组,即   炭[3]

令人惊讶的是,char [3]是三个字符的数组,而不是四个!

答案 1 :(得分:3)

你必须为零终结符再分配一个char:

name = new char[strlen(p) + 1];

答案 2 :(得分:2)

问题是

  1. 您永远不会delete[] name;,因此每次用户调用setname()时,您都会泄漏数组。
  2. 为了适应您需要为'\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到处都是一个糟糕的主意。即使在最好的情况下,也很难阅读,容易出现大量愚蠢的错误,并且基本上不可能使任何接近异常的安全。