C ++ sizeof C风格的字符串/字符数组 - 优化

时间:2017-07-20 14:03:19

标签: c++ arrays string sizeof

我是大学的学生。我主要使用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。那是为什么?

提前致谢。

2 个答案:

答案 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::stringstrlen会更加困难),如果你有一个类有sizeof {{} 1}}你不需要复制构造函数或赋值运算符来处理逻辑来混淆它们。这将显着清理代码并消除其中的大部分内存错误。

答案 1 :(得分:1)

sizeof为您提供c / c ++需要将对象保留在内存中的字节数。在你的情况下(虽然你还没有显示),它看起来像nameaddressphone是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;