以下代码导致程序崩溃,因为
void fractalizeSegment() {
// Assume next != NULL
double deltaX = next->x - x;
double deltaY = next->y - y;
// Add 3 new points labeled a1, a2, a3 from this to next
Point a3(x + 2.0*deltaX/3.0, y + 2.0*deltaY/3.0, next);
double sqr3 = std::sqrt(3.0);
Point a2(x + deltaX/2.0 - sqr3*deltaY/2.0,
y + deltaY/2.0 + sqr3*deltaX/2.0,
&a3);
Point a1(x + deltaX/3.0, y + deltaY/3.0, &a2);
next = &a1;
}
以某种方式优化
void fractalizeSegment() {
next = &a1;
}
在p0 = {x = 0,y = 0,next = 0x7fffffffe100}上调用该方法, 指向p1 = {x = 1,y = 0,next = 0x0}。
通过分析调试器中的程序,我发现当我在方法fractalizeSegment中时:
a1 = {x = 6.9533558075099091e-310, y = 6.9533558075098597e-310, next = 0x7fffffffe190}
在地址a1.next中有
a2 = {x = 6.9533558074508189e-310, y = 4.9406564584124654e-324, next = 0x34}.
尝试依赖(* a2.next).next会导致分段错误。
为什么g ++会像这样优化我的代码?我该如何预防?
我发现当前的解决方法是打印出a1,a2和a3的值, 这阻止了优化。
答案 0 :(得分:7)
a1
是一个本地自动变量,在从函数返回时将被销毁,因此在此之后使用*next
将是未定义的。编译器认为你肯定不会使用这些值,所以为什么还要费心计算它们。
您可能想在堆中创建a1
:
next = new Point(x + deltaX/3.0, y + deltaY/3.0, &a2); //no need of a1.
也许a2
和a3
也应该动态分配,但这取决于你没有展示的Point
的实现。
请记住delete
在某处分配的对象。