我正在编写一个简单的程序,允许我通过将一个字符数组发送到一个公共成员函数来设置一个对象的名称,然后更改一个名为name的私有变量。然后我告诉我的班级将名称变量吐出来,这样我就能看出它是否正常工作 - 但我的输出大部分是乱码。
即我输入
“苹果”
,输出变为
“AAAAA╠╠╠╠Apple”
我注意到,当我改变单词时,重复字符的数量模仿了单词中的字符数 - 但我似乎无法弄清楚我搞砸了程序的位置。这是我的代码:
*注意:现在下面的代码按预期工作。
#include <iostream>
#include <cstring>
using namespace std;
class Item{
public:
~Item() { delete [] name; }
char *setName(char * inputName)
{
name = new char[strlen(inputName)+1];
int n = 0;
for(n = 0; n<strlen(inputName); n++)
name[n] = inputName[n];
name[n] = '\0';
return name;
}
private:
char *name;
};
int main()
{
char objectname[] = "Apple";
Item Apple;
cout << Apple.setName(objectname);
int input;
cin >> input; //pause program
}
答案 0 :(得分:2)
正如我在评论中所说,你永远不会为name
分配内存。使用name[n]
时,您将成为不属于您的解除引用地址。这会导致程序中出现Undefined Behavior,这意味着任何事情都可能发生,并不符合程序的逻辑。它甚至可以编译得很好,但你不能依赖它。
无论如何,您需要为name
分配内存。但为此,您需要知道要分配给它的内存大小。我们不知道内存的大小(它可以是发送到setName
的任意字符串)。因此name
必须是指针:
char* name;
然后我们可以为它分配内存。顺便说一下,char name[]
是一个零大小的数组,在C ++中是非法的。
在setName
内,您需要获取发送给它的字符串的大小。 strlen
适合这项工作,但您还需要为空终结符('\0'
)腾出空间。它是贴在每个字符串末尾的字符,如果你不添加它并稍后尝试打印name
,std::cout
不知道在哪里停止打印每个角色(也是未定义的行为)。
在setName
内,这应该是将动态内存分配给name
:
name = new char[strlen(inputName) + 1];
含义:( inputName
中的字符数+空终止符)。注意:strlen
不计算空终止符。
现在,要设置null-terminator,只需在for()
循环下面执行此操作:
name[n] = '\0';
此外,当您使用name
中的内存时,您必须将其删除。您可以使用delete[]
执行此操作:
delete[] name;
推荐的替代方法是使用std::string
标准C ++字符串类来自行管理内存。