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
- 释放的内存可能在一段时间内不会被新的分配覆盖,因此应用程序可能会继续正常运行,然后在没有明显原因的情况下突然崩溃
- 为新字体分配的地址可能与刚删除的地址相同。这不太可能,但有可能
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