我是大学的学生。我主要使用Java,C ++对我来说是一个新手,所以我可能会犯很多愚蠢的错误而且我有即将到来的考试来应对。别对我太苛刻了。
注意:我不能使用C ++ std :: string,因为我需要使用C字符串来完成大学任务!
参考我的研究以及我询问指针和const
参数(你发现here)的问题我尝试搞乱内存管理,但似乎没有效果,或者我只是误解了关于sizeof
或某些元素的实际大小的某些方面。
这是我的班级人员:
Person.cpp
using namespace std;
Person::Person()
{
Person::name = new (char[64]);
Person::adress = new (char[64]);
Person::phone = new (char[64]);
cout << "standard constructor called; object created, allocated " << sizeof(name) << "+" << sizeof(adress) << "+" << sizeof(phone) << "bytes" << endl;
}
Person::Person(const char *name, const char *adress , const char *phone)
{
Person::name = new (char[strlen(name)]);
Person::adress = new (char[strlen(adress)]);
Person::phone = new (char[strlen(phone)]);
setName(name);
setAdress(adress);
setPhone(phone);
cout << "general constructor called; object created, allocated " << sizeof(this->name) << "+" << sizeof(this->adress) << "+" << sizeof(this->phone) << "bytes" << endl;
};
Person::Person(Person const &other)
{
Person::name = new (char[strlen(other.getName())]);
Person::adress = new (char[strlen(other.getAdress())]);
Person::phone = new (char[strlen(other.getPhone())]);
setName(other.getName());
setAdress(other.getAdress());
setPhone(other.getPhone());
cout << "copy constructor called; object created, allocated " << sizeof(name) << "+" << sizeof(adress) << "+" << sizeof(phone) << "bytes" << endl;
};
Person::~Person()
{
delete [] name;
delete [] adress;
delete [] phone;
cout << "destructor called; object removed" << endl;
};
我试图通过创建一个字符串长度为给定参数的C字符串来节省内存。 认为C字符串是一个字符串数组,节省字符会导致节省内存,例如约翰&#34;&#34;约翰&#34;占用的内存少于#34; Jonathan&#34;的C字符串。
所以现在我不确定我是否只是错误的C字符串或字符串数组的概念,或者我的实现是错误的。
在我的主要内容中,我创建了以下对象:
int main()
{
Person t;
t.printPerson();
cout << "size of t: " << sizeof(t) << endl;
Person p("John", "some street", "0736182");
p.printPerson();
cout << "size of p: " << sizeof(p) << endl;
Person x(p);
x.printPerson();
cout << "size of x: " << sizeof(x) << endl;
Person y("Jonathan", "Lancaster Ave 53", "3584695364");
y.printPerson();
cout << "size of y: " << sizeof(y) << endl;
cin.get();
};
但我的每个对象的大小为24,因此每个成员变量的大小为8。那是为什么?
提前致谢。
答案 0 :(得分:2)
我认为你期望sizeof
运算符的行为与实际不同。我们来看看这段代码,例如:
const char* str = new char[137];
在这里,如果你写sizeof(str)
,你可能会得到4或8,这取决于你的系统,因为sizeof(str)
测量指针str
本身的字节数而不是str
指向的数组中的字节数。因此,在32位系统上,您可能会得到4,而在64位系统上,您可能得到8,与您分配的字符数无关。
不幸的是,C ++没有办法让你获得动态分配的数组所占用的字符数或内存数。你只需要自己跟踪。
同样,在您的main函数中,当您编写sizeof(p)
时,您将测量对象p
使用的字节数,而不是{{1}使用的总字节数它指向的数组。无论指向哪个字符串,您都会p
获得相同的值。
如果您计划在C ++中使用字符串,我强烈建议您使用sizeof(p)
而不是原始C风格的字符串。它们更容易使用,它们会记住它们的长度(因此混淆std::string
和strlen
会更加困难),如果你有一个类有sizeof
{{} 1}}你不需要复制构造函数或赋值运算符来处理逻辑来混淆它们。这将显着清理代码并消除其中的大部分内存错误。
答案 1 :(得分:1)
sizeof
为您提供c / c ++需要将对象保留在内存中的字节数。在你的情况下(虽然你还没有显示),它看起来像name
,address
和phone
是char的指针:
struct Person {
char *name, *address, *phone;
}
指针是一个保存另一个对象地址的变量。因此,根据底层系统,它可以占用32位(4字节)或64位(8字节)(或其他一些数字)。在这种情况下, sizeof 结构人员将用于64位系统 - 24.(每8字节3个指针)。这与您的结果相对应。
sizeof
为您提供浅大小计算。你的字符串由那些指针指向,它们的长度不包括在内。因此,您可能需要创建一个成员函数来为您计算,即
struct Person {
char *name, *address, *phone;
int getSize() {
return strlen(name) + strlen(address) + strlen(phone);
}
};
正如前面的评论中所提到的,c / c ++中的每个char *string
都必须有一个终止字符('\ 0'),它告诉程序字符串的结束位置。因此,如果为字符串分配空间,则应为其提供空间(长度为+ 1)。而且你必须确保这个字符被写为'\ 0'。如果你使用库函数来复制字符串,他们会把它带走,否则你需要手动完成。
void setName(const char *n) {
name = new char[strlen(n) + 1]; // includes needed '0', if exists in 'n'
strcpy(name, n); // copies the string and adds `\0` to the end
}
如果您使用循环来复制字符而不是strcpy
,则需要手动添加:
name[strlen(n)] = 0;