开发者

Is a pointer guaranteed to stay the same no matter how many times you new and delete it?

Here in the following example:

AguiWidget::setGlobalFont(segoe);
label->setFont(AguiWidget::getGlobalFont());
label->resizeToText();

delete segoe;
    segoe = 0;
segoe = new AguiF开发者_开发问答ont(std::string("test.ttf"),24);

I would have expected label to crash because label's font = globalFont which is = to segoe.

Will this always work?

Is it safe to assume that, if I recreate segoe, that all widgets using it will be okay, or will the fonts of the widgets using segoe be affected at some point?

Thanks


No, when you call new and assign the pointer to a different object, the pointer may now point to a completely different memory address. The old memory address is now invalid (since you called delete on it), and any other code which uses that address is now using what's known as a "dangling pointer".

A "dangling pointer" is a pointer which refers to a memory address which used to be valid, but is no longer valid because the object it pointed to was deallocated. Using a dangling pointer will result in undefined behavior, and likely cause your program to crash.

In order for this program to work correctly, the AguiWidget object should make its own internal copy of the pointed-to object, so that it is not dependent on a memory address it doesn't own. If the AguiWidget object in fact does do this, then there is no dangling pointer problem. However, AguiWidget's internal copy of the object won't be affected just because you change the external segoe pointer. Rather, you'd have to call AguiWidget::setGlobalFont again.


No, it is not safe to assume that. There are a few things that might happen:

  • AguiWidget::setGlobalFont may copy the data pointed to into a new allocation. (I can't say for sure without code or docs.) If it does do this, then the code you have pasted is fine.
  • The freed memory may not be overwritten by a new allocation for some time, so the application may continue to function just fine and then crash later out of the blue for no apparent reason.
  • The allocation for the new font may be assigned the same address as the one that was just deleted. This is unlikely, but possible.


Is it safe to assume that, if I recreate segoe, that all widgets using it will be okay, or will the fonts of the widgets using segoe be affected at some point?

That depends on whoever wrote the widget toolkit you are using. If the tookit is designed with any bit of sense, when you pass a pointer to a method, the method shouldn't make assumptions about the pointer after the method terminates. That said, nobody says it is designed that way.

You would have to consult documentation for whatever widget toolkit you are using.


If you recreate segoe, all widgets using it before will have to point to the new location, as the pointer itself, the 32-bit or 64-bit value of it, will undoubtedly have changed. You currently have a dangling pointer which is a serious issue.


It depends really. If the class you are sending it to performs a deep copy, then yes you are probably safe. If it doesn't then you will have the issue that Charles Salvia is saying.


Nope, there's no such guarantee.

But if you want to reuse the old memory and create a new object in the same place, there's a low-level feature called placement new:

instead of:

delete segoe;
segoe = new AguiFont(...)

you can:

segoe.~AguiFont(); // destructor called, no memory released -
                   // the pointer now points at allocated, but uninitialized memory
new(segoe) AguiFont(...); // costructor called on the same memory place
                          // the pointer is valid again

But for that to be safe and correct, I believe the previous and the new class have to be the same. Consider what would happen if they had different sizes, for example (the allocated memory's still the same size!).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜