解除“新”指针是否被视为好的风格?

时间:2022-05-01 21:45:18

To avoid keep having to use -> and instead work directly with the object, is it acceptable practice to do:

为了避免继续使用 - >而是直接使用对象,可以接受的做法是:

obj x = *(new obj(...));...delete &obj;

4 个解决方案

#1


29  

This is not just poor practice, but:

这不仅仅是糟糕的做法,而是:

  1. Leaking memory (most likely, unless you are using some pattern that is not visible from the code you provided), since obj will store a copy of the original object created by the new expression, and the pointer to that object returned by new is lost;
  2. 泄漏内存(很可能,除非您使用的是从您提供的代码中看不到的某些模式),因为obj将存储由新表达式创建的原始对象的副本,并且指向new返回的该对象的指针将丢失;

  3. Most importantly, undefined behavior, since you are passing to delete a pointer to an object that was not allocated with new. Per paragraph 5.3.5/2 of the C++11 Standard:
  4. 最重要的是,未定义的行为,因为您要传递删除指向未使用new分配的对象的指针。根据C ++ 11标准的第5.3.5 / 2段:

[...] In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined.

[...]在第一个替代(删除对象)中,delete的操作数的值可以是空指针值,指向由前一个new-expression创建的非数组对象的指针,或指向子对象的指针(1.8)代表这种对象的基类(第10条)。如果不是,则行为未定义。

#2


9  

No, and in fact this leads to a leak. x is copy initialized, so the original object pointed to by new obj is lost.

不,实际上这会导致泄漏。 x是初始化的副本,因此新obj指向的原始对象将丢失。

Just use

obj x(...);

No need for dynamic allocation. Or

无需动态分配。要么

obj x = obj(...);

if you must (doubt it).

如果你必须(怀疑)。

#3


7  

Certainly not; that copies the dynamic object to an automatic variable, loses the only pointer to it, and then attempts to delete the automatic copy. You've got a memory leak and an invalid deletion.

当然不是;将动态对象复制到自动变量,丢失指向它的唯一指针,然后尝试删除自动副本。您有内存泄漏和无效删除。

Much better would be to use an automatic variable in the first place:

更好的方法是首先使用自动变量:

obj x(...);...// no need to delete anything

or, if it really must be dynamic for some reason (because it's too big for the stack, or you don't always want to destroy it here), then use a smart pointer, and a reference if you really don't like ->

或者,如果由于某种原因它确实必须是动态的(因为它对于堆栈来说太大了,或者你并不总是想在这里销毁它),那么使用智能指针和引用如果你真的不喜欢 - >

std::unique_ptr<obj> p(new obj(...));obj & x = *p;...// still no need to delete anything

Changing your x into a reference would be valid (as long as you're careful that exceptions, early function returns, etc. won't cause a leak), but would cause howls of confusion among anyone unfortunate enough to have to maintain it.

将x转换为引用将是有效的(只要您小心异常,早期函数返回等不会导致泄漏),但会导致任何不幸的人不得不维持它的混乱。

#4


0  

You cannot delete your object properly if you do it like that.

如果您这样做,则无法正确删除对象。

Implicitly you do the following.

隐含地执行以下操作。

class A{public:  int test (void) { return 1; }};int main (void){  A * p = new A;  A v(*p);  //...  delete &v; // &v != p and v is not constructed via new!  return 0;}

If you want to work with an object-like-syntax you can bind a reference to the object.

如果要使用类似对象的语法,可以绑定对象的引用。

class A{public:  int test (void) { return 1; }};int main (void){   A * p = new A;   A & r = *p;   int i = r.test();   delete p;   return 0;}

If you delete your object through the same pointer, there will be no leak.

如果通过相同的指针删除对象,则不会发生泄漏。

#1


29  

This is not just poor practice, but:

这不仅仅是糟糕的做法,而是:

  1. Leaking memory (most likely, unless you are using some pattern that is not visible from the code you provided), since obj will store a copy of the original object created by the new expression, and the pointer to that object returned by new is lost;
  2. 泄漏内存(很可能,除非您使用的是从您提供的代码中看不到的某些模式),因为obj将存储由新表达式创建的原始对象的副本,并且指向new返回的该对象的指针将丢失;

  3. Most importantly, undefined behavior, since you are passing to delete a pointer to an object that was not allocated with new. Per paragraph 5.3.5/2 of the C++11 Standard:
  4. 最重要的是,未定义的行为,因为您要传递删除指向未使用new分配的对象的指针。根据C ++ 11标准的第5.3.5 / 2段:

[...] In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined.

[...]在第一个替代(删除对象)中,delete的操作数的值可以是空指针值,指向由前一个new-expression创建的非数组对象的指针,或指向子对象的指针(1.8)代表这种对象的基类(第10条)。如果不是,则行为未定义。

#2


9  

No, and in fact this leads to a leak. x is copy initialized, so the original object pointed to by new obj is lost.

不,实际上这会导致泄漏。 x是初始化的副本,因此新obj指向的原始对象将丢失。

Just use

obj x(...);

No need for dynamic allocation. Or

无需动态分配。要么

obj x = obj(...);

if you must (doubt it).

如果你必须(怀疑)。

#3


7  

Certainly not; that copies the dynamic object to an automatic variable, loses the only pointer to it, and then attempts to delete the automatic copy. You've got a memory leak and an invalid deletion.

当然不是;将动态对象复制到自动变量,丢失指向它的唯一指针,然后尝试删除自动副本。您有内存泄漏和无效删除。

Much better would be to use an automatic variable in the first place:

更好的方法是首先使用自动变量:

obj x(...);...// no need to delete anything

or, if it really must be dynamic for some reason (because it's too big for the stack, or you don't always want to destroy it here), then use a smart pointer, and a reference if you really don't like ->

或者,如果由于某种原因它确实必须是动态的(因为它对于堆栈来说太大了,或者你并不总是想在这里销毁它),那么使用智能指针和引用如果你真的不喜欢 - >

std::unique_ptr<obj> p(new obj(...));obj & x = *p;...// still no need to delete anything

Changing your x into a reference would be valid (as long as you're careful that exceptions, early function returns, etc. won't cause a leak), but would cause howls of confusion among anyone unfortunate enough to have to maintain it.

将x转换为引用将是有效的(只要您小心异常,早期函数返回等不会导致泄漏),但会导致任何不幸的人不得不维持它的混乱。

#4


0  

You cannot delete your object properly if you do it like that.

如果您这样做,则无法正确删除对象。

Implicitly you do the following.

隐含地执行以下操作。

class A{public:  int test (void) { return 1; }};int main (void){  A * p = new A;  A v(*p);  //...  delete &v; // &v != p and v is not constructed via new!  return 0;}

If you want to work with an object-like-syntax you can bind a reference to the object.

如果要使用类似对象的语法,可以绑定对象的引用。

class A{public:  int test (void) { return 1; }};int main (void){   A * p = new A;   A & r = *p;   int i = r.test();   delete p;   return 0;}

If you delete your object through the same pointer, there will be no leak.

如果通过相同的指针删除对象,则不会发生泄漏。