简体   繁体   English

当可以使用=运算符为其分配字符串时,为什么在分配之前使用new运算符为字符串动态分配内存?

[英]why use the new operator to dynamically allocate memory for a string before assigning, when we can use the = operator to assign a string to it?

I am new to C++ and the concept of strings, why do I have to use the new operator to dynamically allocate resources when I can do it just assigning the string using the = operator ? 我是C ++和字符串概念的新手,为什么我只能使用=运算符分配字符串,但必须使用new运算符动态分配资源? (this is my first question and sorry for being messy) (这是我的第一个问题,对不起,我很混乱)

student(const char* n){
    len=strlen(n);
    name=new[len+1];
    strcpy(name,n);
}

where student is a dynamic constructor of class student. 学生是班级学生的动态构造函数。

class student {
    int len; 
    char *name; 
public: 
    student(const char *);
}

If I write my dynamic constructor as given below, will it not have the same outcome? 如果我按如下所示编写动态构造函数,结果是否会有所不同?

student(const char* n){
    len=strlen(n); 
    name=n;
}

A char * s; char * s; is not a string. 不是字符串。 It's a pointer-- a handle -- to a block of memory in which each element of that block is the size of a char . 它是一个内存块的指针(一个句柄) ,其中该内存块的每个元素都是char的大小。

You have to use new to allocate a box. 您必须使用new来分配一个盒子。

Then you "attach" your handle to that box. 然后,您将手柄“附加”到该框。

Then you fill up the box with data-- this is the string. 然后,用数据填充框-这是字符串。

// we have a handle which will fit a box that contains a bunch of "char"
char * s;
// now let's get a box that's big enough to hold the data
// and attach it to the handle
s = new char [len];
// now let's fill up the box with the data from source_str
strcpy (source_str, s);
// also, don't forget that you MUST delete anything that you allocate
delete [] s;

This is an extremely important concept in programming especially for system languages like C++. 这是编程中非常重要的概念,尤其是对于像C ++这样的系统语言而言。

C++, and other languages that support classes and objects use constructors and destructors to help control any memory that an object uses by following this cycle: C ++和其他支持类和对象的语言使用构造函数和析构函数来遵循以下循环来帮助控制对象使用的任何内存:

  • construct the object 构造对象
  • do something with the object 对对象做某事
  • destruct the object 破坏对象

Notice how this is exactly the same as the cycle of memory management. 请注意,这与内存管理周期完全相同。

The reason you're practicing on strings right now is to get you used to the technique of: 您现在正在对字符串进行练习的原因是使您习惯于以下技术:

  • allocating a block of memory 分配一块内存
  • doing something with it 用它做点什么
  • then freeing up that block of memory later 然后稍后释放该内存块

Here's a straight-forward example: 这是一个简单的例子:

#include <iostream>
using namespace std;

char * get_a_string () {
    // notice that s is allocated "on the stack"
    // which means that it goes out of scope and is
    // not available outside of this function
    auto s = "Adam Smith";

    //char * name = s;  // this WILL NOT WORK because the memory that
                        // that s points to will go out of scope
                        // and then name will point to invalid memory

    // we need to make s available to other parts of the
    // program so we allocate some memory "on the heap"
    // because the heap doesn't go out of scope
    char * name = new char [strlen (s)];

    // now since the contents of s have been copied into the heap
    // they'll still be available outside of this function
    strcpy (s, name);

    return name;
}

void do_something (char * c) {
    cout << c << endl;
}

int main () {    
    char * name = get_a_string ();

    do_something (name);

    // rule of thumb:
    //     anything you allocate with "[]" you must also delete with "[]"...
    delete [] name;
}

Pay careful attention to the cycle of memory in the above program. 请仔细注意上述程序中的存储周期。 Notice when it's "newed-up" and "deleted". 注意它是“新的”和“删除的”。 Wouldn't it be tricky to keep track of which functions allocated memory and which ones deleted it so that you could new and delete at the proper times? 跟踪哪些函数分配了内存,哪些函数删除了内存,这样您就可以在适当的时候进行新建和删除,这不是很棘手的事情吗?

Here's an example of a Student class similar to what you're going for. 这是一个与您要学习的学生类相似的示例。 Notice how the memory is allocated in one place and is easy to track: 请注意,内存是如何在一个位置分配的,并且易于跟踪:

#include <iostream>
using namespace std;

class Student {
    public:
        // This is NOT a string.
        // It does not contain any data.
        // It only points to a block/box of data that is
        // split into chunks the size of a char
        char * my_name;

        Student (const char * new_name) {
            // we have to find out how long new_name is
            auto name_len = strlen (new_name);

            // now we need to make a box big enough to hold it
            // this is called allocation
            my_name = new char [name_len];

            // now we must copy the contents from the box that
            // new_name points to into the box that my_name points to
            strcpy (new_name, my_name);
        }

        ~Student () {
            // it's very important to free up the memory we allocated
            // in the constructor
            delete [] my_name;
        }
};

int main () {
    // so here the name is allocated and initialized so that we can use some_student elsewhere in our program
    Student some_student ("Adam Smith");

    // making use of the block of memory...
    cout << "student's name is: " << some_student.my_name << endl;

    return 0;
}
// at the end of the scope the destructor for some_student will be called
// which will delete some_student.my_name so that other programs can use
// that memory

This modern approach uses std::string but it is still exactly the same thing . 这种现代方法使用std :: string, 但仍然完全一样

YES. 是。 std::string does exactly the same thing that your simple Student class does . std :: string 与简单的Student类完全一样

#include <string>

class Student {
    public:
        std::string name;

        Student (const char * s) {
            // name is a std::string
            // that means that std::string has a constructor
            // and a copy operator which will do exactly what you
            // were doing using new and delete
            // It's just hidden and done for us BUT IT'S STILL BEING DONE.
            name = s;
        }

        ~Student () {
            // ...
        }
        // destructors for all of a class' members will be
        // called at the end of a class' destructor!
        // this means that since "my_name" is a std::string
        // its destructor will delete the memory that std::string
        // allocated in its constructor for me and I don't have to
        // do anything!
};

int main () {
    // so here the name is allocated and initialized
    // so that we can use some_student elsewhere in our program
    auto some_student = Student { "Adam Smith" };

    // making use of the block of memory...
    cout << "student's name is: " << some_student.my_name << endl;

    return 0;
}
// at the end of the scope the destructor for some_student will be called
// which will delete some_student.my_name so that other programs can use
// that memory

Here's what Bjarne Stroustrup had to say about learning to program using C++ . 这是Bjarne Stroustrup关于使用C ++进行编程学习所要说的。

When you allocate the buffer you own it, you can modify it but you also must delete it. 分配自己拥有的缓冲区时,可以对其进行修改,但也必须删除它。

I do not think the above case should compile. 我认为上述情况不应该编译。 You are assigning const char * to char * that should not be allowed by the compiler. 您正在将const char *分配给char * ,这是编译器不允许的。 If you changed your member to be const char* you still could possibly hand over to the constructor a string that later ceases to exist and then you got a bad pointer. 如果将成员更改为const char*您仍然可以将构造函数的字符串交给后来不再存在的字符串,然后得到一个错误的指针。

the only time it should not matter is if you know that you are assigning constant strings such as `const char * var="my literal string". 唯一没有关系的时间是您是否知道要分配常量字符串,例如“ const char * var =“我的文字字符串”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当我使用new运算符分配大小为1k字节的内存时,操作系统在Windows中会做什么? - what will OS do in Windows when I use the operator new to allocate memory with the size of 1k bytes? 使用哪个 - “operator new”或“operator new []” - 在C ++中分配一块原始内存? - Which to use - “operator new” or “operator new[]” - to allocate a block of raw memory in C++? 为什么使用“new”运算符? - Why use the "new" operator? 将指针分配给数组的内存地址时,为什么不必使用地址运算符? - When assigning a pointer to the memory address of an array, why don't you have to use the address operator? 新操作员无法分配内存 - new operator unable to allocate memory 为什么编译器在执行operator&lt;&lt;时不能使用类的std::string转换函数? - Why can't the compiler use the std::string conversion function of the class when perform operator<<? 为什么运算符new []为数组的大小分配内存? - Why does operator new[] allocate memory for the size of the array? 重载新运算符时,它不会为char指针分配内存 - when overloading new operator it doesnt allocate memory for char pointer 当使用new()运算符分配内存时,mudflap会抛出核心转储 - mudflap throws core dump when using new() operator to allocate memory C ++新运算符分配新内存 - C++ new operator allocate new memory
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM