C++ 无论你新建和删除了多少次,指针都能保证保持不变吗?

C++ 无论你新建和删除了多少次,指针都能保证保持不变吗?,c++,C++,在下面的示例中: AguiWidget::setGlobalFont(segoe); label->setFont(AguiWidget::getGlobalFont()); label->resizeToText(); delete segoe; segoe = 0; segoe = new AguiFont(std::string("test.ttf"),24); 我本以为label会崩溃,因为label的font=globalFont=to segoe 这会一直有效

在下面的示例中:

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

delete segoe;
    segoe = 0;
segoe = new AguiFont(std::string("test.ttf"),24);
我本以为label会崩溃,因为label的font=globalFont=to segoe

这会一直有效吗

如果我重新创建segoe,所有使用它的小部件都会正常,或者使用segoe的小部件的字体在某个时候会受到影响,这是安全的吗


谢谢

否,当您调用
new
并将指针指定给不同的对象时,指针现在可能指向完全不同的内存地址。旧内存地址现在无效(因为您在其上调用了
delete
),而使用该地址的任何其他代码现在都在使用所谓的“悬空指针”

“悬空指针”是一个指针,它指向一个内存地址,该地址过去是有效的,但由于指向的对象被解除分配,因此不再有效。使用悬空指针将导致未定义的行为,并可能导致程序崩溃


为了使该程序正常工作,AguiWidget对象应该为指向的对象创建自己的内部副本,这样它就不依赖于自己不拥有的内存地址。如果
AguiWidget
对象实际上做到了这一点,那么就不存在悬空指针问题。但是,
AguiWidget
对象的内部副本不会因为更改外部
segoe
指针而受到影响。相反,您必须再次调用
AguiWidget::setGlobalFont

否,当您调用
new
并将指针指定给不同的对象时,指针现在可能指向完全不同的内存地址。旧内存地址现在无效(因为您在其上调用了
delete
),而使用该地址的任何其他代码现在都在使用所谓的“悬空指针”

“悬空指针”是一个指针,它指向一个内存地址,该地址过去是有效的,但由于指向的对象被解除分配,因此不再有效。使用悬空指针将导致未定义的行为,并可能导致程序崩溃

为了使该程序正常工作,AguiWidget对象应该为指向的对象创建自己的内部副本,这样它就不依赖于自己不拥有的内存地址。如果
AguiWidget
对象实际上做到了这一点,那么就不存在悬空指针问题。但是,
AguiWidget
对象的内部副本不会因为更改外部
segoe
指针而受到影响。相反,您必须再次调用
AguiWidget::setGlobalFont

如果我重新创建segoe,所有使用它的小部件都会正常,或者使用segoe的小部件的字体在某个时候会受到影响,这是安全的吗

这取决于谁编写了您正在使用的小部件工具包。如果tookit的设计有一定的道理,那么当您向方法传递指针时,该方法不应该在方法终止后对指针进行假设。也就是说,没有人说它是这样设计的

您必须查阅您正在使用的任何小部件工具包的文档

如果我重新创建segoe,所有使用它的小部件都会正常,或者使用segoe的小部件的字体在某个时候会受到影响,这是安全的吗

这取决于谁编写了您正在使用的小部件工具包。如果tookit的设计有一定的道理,那么当您向方法传递指针时,该方法不应该在方法终止后对指针进行假设。也就是说,没有人说它是这样设计的


您必须查阅您正在使用的任何小部件工具包的文档。

不,假设这样做是不安全的。可能会发生一些事情:

  • AguiWidget::setGlobalFont
    可以将指向的数据复制到新的分配中。(如果没有代码或文档,我不能确定。)如果它做到了这一点,那么您粘贴的代码就可以了
  • 释放的内存可能在一段时间内不会被新的分配覆盖,因此应用程序可能会继续正常运行,然后在没有明显原因的情况下突然崩溃
  • 为新字体分配的地址可能与刚删除的地址相同。这不太可能,但有可能

不,这样假设是不安全的。可能会发生一些事情:

  • AguiWidget::setGlobalFont
    可以将指向的数据复制到新的分配中。(如果没有代码或文档,我不能确定。)如果它做到了这一点,那么您粘贴的代码就可以了
  • 释放的内存可能在一段时间内不会被新的分配覆盖,因此应用程序可能会继续正常运行,然后在没有明显原因的情况下突然崩溃
  • 为新字体分配的地址可能与刚删除的地址相同。这不太可能,但有可能

如果重新创建segoe,以前使用它的所有小部件都必须指向新位置,因为指针本身,即它的32位或64位值,无疑会发生变化。您当前有一个悬空指针,这是一个严重的问题。

如果重新创建segoe,以前使用它的所有小部件都必须指向新的位置,因为指针本身,它的32位或64位值,无疑会发生变化。您当前有一个悬空指针,这是一个严重的问题。

这取决于实际情况。如果要发送它的类执行深度复制,那么是的,您可能是安全的。如果没有,那么你就会有查尔斯·萨尔维亚所说的问题。

这要看情况而定。如果要发送它的类执行深度复制,那么是的,您可能是安全的。如果没有,那么你将面临查尔斯·萨尔维亚的问题
delete segoe;
segoe = new AguiFont(...)
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