【问题标题】:Using new keyword/operator in C++在 C++ 中使用新的关键字/运算符
【发布时间】:2017-11-27 13:01:23
【问题描述】:

以下语句的结果是什么?

std::string p;
new (&p) std::string("New word");

它会创建一个新的堆分配吗?还是它只是替换静态变量?它与以下有何不同?

p = std::string("New word");
p = new std::string("New word");

编辑: 多谢你们。是的,它似乎是一个新的展示位置。

【问题讨论】:

  • 如果你发布p的定义,这个问题会更有意义。
  • 可能是 stackoverflow.com/q/13370935/10077 的骗子,虽然我犹豫要不要锤它。
  • 看起来像是新展示位置
  • 第一个代码是未定义的行为(如果一个对象有一个做某事的析构函数,你不能在不先调用析构函数的情况下将它放在它的顶部)。第二个不会编译

标签: c++


【解决方案1】:
  • new (&p) std::string("New word"); 正在使用新展示位置&p 必须指向大小至少为 sizeof(std::string) 字节的预先存在的内存块。 std::string 对象将在该内存中构造,而不是在新分配的内存块中。该对象必须在使用完毕后直接调用其析构函数来销毁,例如:

    char buffer[sizeof(std::string)];
    std::string *p = new (buffer) std::string("New word");
    ...
    p->~std::string();
    
  • p = std::string("New word"); 可能会做不同的事情,具体取决于使用它的上下文:

    • 如果在变量声明语句中使用,p 分配在堆栈(自动)或堆(动态)内存(取决于上下文)上,并使用 std::string 值复制构造:

      some_type p = std::string("New word");
      //
      // same as:
      // some_type p(std::string("New word"));
      //
      // if some_type=std::string, same as:
      // std::string p("New word");
      ...
      
    • 如果在预先存在的对象的赋值语句中使用,它会分配一块临时堆栈(自动)内存,在该内存中构造一个新的临时 std::string 对象,将该临时对象分配给 @ 987654331@,然后销毁临时对象并释放临时内存。

  • p = new std::string("New word"); 正在分配一个新的堆(动态)内存块,在该内存中构造std::string 对象,然后将内存地址分配给p 指针。该对象必须使用delete手动销毁:

    std::string *p = new std::string("New word");
    ...
    delete p;
    

在所有三种情况下,std::string 对象都包含一个指向其字符数据的内部指针,该指针可能指向堆栈(自动)或堆(动态)上的内存,具体取决于分配 std::string 的位置,什么它采用的优化等。

【讨论】:

  • p = std::string("New word"); 没有初始化新变量呢?
  • 唯一可以编译的方法是如果p 是一个实际的std::string 对象(或带有operator= 的对象,接受std::string 作为输入),而不是std::string* 指针到一个对象。
  • 这就是我要问的,例如std::string p; ...; p = std::string("New word");。这会创建一个临时字符串并复制它,还是复制省略会绕过它?
  • 在您的第一个示例中,由于 char 缓冲区未与 std::string 对齐(这就是 std::aligned_storage 的用途),它可能会失败
  • @Barmar: std::string p; ...; p = std::string("New word"); 实际上是std::string p; ...; p.operator=(std::string("New word")); 它正在构造一个临时对象并将其传递给p,然后它会复制数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-30
  • 2019-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多