相关疑难解决方法(0)

为什么在C++中没有放置删除表达式?

为什么C++没有直接对应于贴图新的贴片删除,即调用析构函数并调用适当的贴片删除操作符?

例如:

MyType *p = new(arena) MyType;
...
//current technique
p->~MyType();
operator delete(p, arena);

//proposed technique
delete(arena) p;
Run Code Online (Sandbox Code Playgroud)

c++ new-operator delete-operator c++11

30
推荐指数
4
解决办法
1万
查看次数

为什么不〜后跟:: parse

在Andrei Alexandrescu关于错误处理的讨论中:

参见C++和2012年之后:Andrei Alexandrescu - C++中的系统错误处理(大约30分钟)

Andrei提供以下代码:

~Expected()
{
    using std::exception_ptr;
    if (gotHam) ham.~T();
    else spam.~exception_ptr();
}
Run Code Online (Sandbox Code Playgroud)

这个析构函数正在清理一个union包含某种类型T或一个类型的析构函数std::exception_ptr.工会填充使用placement new.

然后安德烈解释说这using std::exception_ptr;是必要的,因为以下代码不解析:

    else spam.~std::exception_ptr();
Run Code Online (Sandbox Code Playgroud)

这意味着如果需要在不同的命名空间中显式调用类的析构函数,则始终需要使用using指令.

为什么第二个例子不解析?

以下代码是否是有效的替代方案?

    else delete spam;
Run Code Online (Sandbox Code Playgroud)

这是否与显式调用析构函数具有相同的效果 std::exception_ptr

c++ c++11

14
推荐指数
2
解决办法
362
查看次数

对从放置new获取的指针使用operator delete的合法性

我确信这段代码应该是非法的,因为它显然不会起作用,但它似乎被C++ 0x FCD所允许.

class X { /* ... */};
void* raw = malloc(sizeof (X));
X* p = new (raw) X(); // according to the standard, the RHS is a placement-new expression
::operator delete(p); // definitely wrong, per litb's answer
delete p; // legal?  I hope not
Run Code Online (Sandbox Code Playgroud)

也许你们中的一位语言律师可以解释标准如何禁止这一点.

还有一个数组形式:

class X { /* ... */};
void* raw = malloc(sizeof (X));
X* p = new (raw) X[1]; // according to the standard, the RHS is a placement-new expression
::operator delete[](p); // definitely …
Run Code Online (Sandbox Code Playgroud)

c++ placement-new language-lawyer delete-operator

12
推荐指数
2
解决办法
1051
查看次数

操作员删除功能的放置形式

在他的新书TC++ PL4中, Stroustrup 对用户控制的内存分配和放置 - 或者更具体地说,关于神秘的"放置"的惯常做法 略有不同.在书的教派.11.2.4,Stroustrup写道:newdelete

delete除了可能通知垃圾收集器已删除的指针不再安全地派生之外,"placement "运算符不执行任何操作.

这意味着声音编程实践将通过调用放置delete来显式调用析构函数.

很公平.但是,没有更好的语法来调用放置而delete不是模糊

::operator delete(p);
Run Code Online (Sandbox Code Playgroud)

我问的原因是Stroustrup的教派.11.2.4没有提到这种奇怪的语法.事实上,Stroustrup没有详述此事; 他根本没有提到任何语法.我隐约不喜欢这样的外观::operator,它将命名空间解析的问题插入到与名称空间无关的内容中.不存在更优雅的语法吗?

作为参考,这里是Stroustrup在更全面的上下文中的引用:

默认情况下,operator new在免费商店中创建其对象.如果我们想要在其他地方分配对象怎么办?...我们可以通过提供带有额外参数的allocator函数将对象放在任何地方,然后在使用时提供这样的额外参数new:

void* operator new(size_t, void* p) { return p; }

void buf = reinterpret_cast<void*>(0xF00F);
X* p2 = new(buf) X;
Run Code Online (Sandbox Code Playgroud)

由于这种用法,new(buf) X提供额外参数的语法operator new()称为放置语法. 请注意,每个都operator new()将大小作为其第一个参数,并且隐式提供分配的对象的大小.在operator new()由所使用的new操作者是由通常的说法,匹配规则选择; 每个operator new()都有一个size_t作为它的第一个参数.

"放置" operator new()是最简单的这种分配器.它在标准标题中定义<new>: …

c++ placement-new

9
推荐指数
1
解决办法
848
查看次数

在C++ 11中,如何调用new并为对象保留足够的内存?

我有一个以这种方式描述的类:

class Foo {
    int size;
    int data[0];

public:
    Foo(int _size, int* _data) : size(_size) {
        for (int i = 0 ; i < size ; i++) {
            data[i] = adapt(_data[i]);
        }
    }

    // Other, uninteresting methods
}
Run Code Online (Sandbox Code Playgroud)

我无法改变那门课程的设计.

如何创建该类的实例?在调用构造函数之前,我必须保留足够的内存来存储其数据,因此它必须在堆上,而不是在堆栈上.我想我想要的东西

Foo* place = static_cast<Foo*>(malloc(sizeof(int) + sizeof(int) * size));
*place = new Foo(size, data);  // I mean : "use the memory allocated in place to do your stuff !"
Run Code Online (Sandbox Code Playgroud)

但我找不到办法让它发挥作用.

编辑:正如评论员所注意到的,这不是一个非常好的整体设计(使用非标准技巧data[0]),唉这是一个我不得不使用的库...

c++ memory-management c++11

8
推荐指数
2
解决办法
554
查看次数

在C++中删除和调用析构函数有什么区别

如标题所述,这是我的代码:

class Foo {

    public:
        Foo (int charSize) {
            str = new char[charSize];
        }
        ~Foo () {
            delete[] str;
        }
    private:
        char * str;
};
Run Code Online (Sandbox Code Playgroud)

对于这个类,有什么区别:

int main () {
    Foo* foo = new Foo(10);
    delete foo;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

int main () {
    Foo* foo = new Foo(10);
    foo->~Foo();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ destructor memory-management

6
推荐指数
1
解决办法
4297
查看次数

我是否需要销毁新类的每个实例?

本质上,如果我创建一个新类的多个实例,我是否需要为每个实例调用析构函数,或者一旦销毁每个实例就调用它(如果我使用含糊/错误的术语,我道歉,构造函数/析构函数是概念我还没完全掌握).

更具体地说,这是我正在使用的一些代码(如果样式不好,我将不得不再次道歉,我对学校问题有了一个想法,并希望快速得到代码).

while(read >> f >> l >> t >> s >> sta >> acct >> bal)
{
    cout << "test" << endl;
    ptr[i] = new account(f,l,t,s,sta,acct,bal);
    ptr[i]->printcontents();
    cout << "test" << endl;
    i++;
    cout << i << endl;
}
Run Code Online (Sandbox Code Playgroud)

所以为了这个问题,假设这个循环三次.我是否只需要调用"帐户"的析构函数来销毁所有三个新帐户实例,或者一个调用会离开另外两个?这甚至是一个好习惯吗?

编辑:我注意到我的一些帖子被切断,所以我添加了最后几行,但人们已经解决了这个问题.我是用户指针的原因纯粹是因为作业决定了我这样做; 坦率地说,我现在没有看到使用它们的重点,但我认为它们在某个地方变得有用.我还应该补充说,动态内存分配也应该在赋值中使用.

c++ constructor pointers destructor

5
推荐指数
1
解决办法
384
查看次数

calloc(),malloc()vs new-ing一个内部有unordered_map的结构

我正在创建一个结构,其中的字段是堆上的unordered_map.当我使用new时,我可以毫无问题地添加它.但是使用calloc,我得到一个插入错误,因为桶大小为0.我调用reserve后工作正常.

那么,当在结构上调用calloc时,unordered_map构造函数不会运行吗?我很困惑为什么如果它在一个新版本的结构中,它似乎具有非零桶大小.除了召唤预备队之外,还有更好的方法吗?(在这种情况下我不能使用删除,所以我需要坚持使用calloc调用)

c++ malloc memory-management calloc

0
推荐指数
1
解决办法
1295
查看次数