未定义的新运算符如何导致 C++ 中的未定义行为?

How does an undefined new operator lead to undefined behaviour in C++?

这里我有一段C++代码:

#include <iostream>
#include <map>
#include <string>
#include <cstdlib>

using namespace std;

class Person {
    private:
        int year;
        Person(const Person& pers);
    public:
        Person(int y): year(y)
        { cout << "Default constructor" << endl;}

        ~Person()
        {
            cout << "Destructor " << endl;
        }

        int get_year() const
        {
            return year;
        }
};


int main()
{
    map<string, Person*> test;
    test.insert(pair<string, Person*>("ini_1", new Person(2)));
    return 0;
}

输出

Default constructor
  1. 从输出中,我想知道如何在给定 new Person(2) 的情况下删除 test 映射的值,而无需像首先那样对其进行编码
Person* per = new Person(2)
test.insert(pair<string, Person*>("ini_1", per));

delete per;
  1. 不用先这样定义
Person* per = new Person(2)
test.insert(pair<string, Person*>("ini_1", per));

它会导致未定义的行为吗?您能否描述未定义行为的更多细节?尤其是它是如何存在于记忆中的?谢谢。

  1. 如果不正确,我可以这样用Person代替new Person吗?它会导致任何未定义的行为吗?
#include <iostream>
#include <map>
#include <string>
#include <cstdlib>

using namespace std;

class Person {
    private:
        int year;

    public:
        Person(int y): year(y)
        { cout << "constructor" << endl;}

        Person(const Person& pers)
        {
            cout << "copy constructor" << endl;
        }
        ~Person()
        {
            cout << "Destructor " << endl;
        }

        int get_year() const
        {
            return year;
        }
};


int main()
{
    map<string, Person> test;

    test.insert(pair<string, Person>("ini_1", Person(2)));

    return 0;
}

输出:

constructor
copy constructor
copy constructor
Destructor
Destructor
Destructor
  1. 我不明白为什么构造函数运行一次,复制构造函数运行两次。你能解释一下他们发生的地方吗?

谢谢。

From the output, I can see the destructor did not run. I would like to know, how I can delete the new pointer without defining it?

您声明了 ;指向 Person 的指针的映射

map<string, Person*> test;

所以Person类型的对象在这条语句中只创建了一次

test.insert(pair<string, Person*>("ini_1", new Person(2)));

此外,地图处理的是指针而不是对象。

您需要明确删除创建的对象。例如

for ( auto &item : test )
{
    delete item.second;
     item.second = nullptr;
}

如果您不删除分配的对象(或多个对象),则会发生内存泄漏。

I don't understand why the constructor ran for once and copy constructor ran for twice. Can you please explain where they happened?

在此声明中

test.insert(pair<string, Person>("ini_1", Person(2)));

显式调用转换构造函数以创建 Person Person(2) 类型的对象。

然后调用class Person 的复制构造函数来创建pair<string, Person> 类型的对象。

最后,这个对象被复制到映射中,再次为数据成员对中的第二个数据成员调用 Person 类型的复制构造函数。

因此创建了三个对象并调用了对象的三个析构函数。