从main开始,我试图在mymath.cpp中调用一个prime函数 - 它有一些 我不明白的非常奇怪的行为。 (注意,算法不起作用 然而 - 但这对我来说并不奇怪。)
奇怪的是,如果我注释掉这一行:
cout << "n:" << lastPrime->pnum <<"\n";
...在mymath.cpp中,我的main循环只运行两次。如果我把它留在里面,我的主循环一直运行到i = 50;
的main.cpp
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include "stat.h"
#include "mymath.h";
using namespace std;
int main()
{
for (int i = 3; i<= 50; i++)
{
if (isPrime(i))
{
cout << i << " is prime!\n";
}
else
{
cout << i << " is NOT prime\n";
}
}
return 0;
}
MYMATH.CPP
#include "mymath.h"
#include <math.h>
#include <iostream>
using namespace std;
prime two;
prime * lastPrime = &two;
prime * firstPrime = &two;
bool isPrime(long long n)
{
two.pnum=2;
prime * currentPrime = &two;
if ( n < 2)
return false;
long long squareRoot = sqrt(n);
while(true)
{
if (n % currentPrime->pnum==0)
{
//n is divisible by a prime number, nothing left to do.
return false;
}
else
{
//n is not divisible by a prime... check next one
{
if (currentPrime->pprime == 0 || currentPrime->pnum > squareRoot)
{
//this is prime
prime addPrime;
addPrime.pnum=n;
addPrime.pprime=0;
lastPrime->pprime=&addPrime;
lastPrime=&addPrime;
cout << "n:" << lastPrime->pnum <<"\n";
return true;
}
else
{
//may not be prime, check next
currentPrime = currentPrime->pprime;
}
}
}
}
return true;
}
答案 0 :(得分:3)
代码undefined behaviour作为名为addPrime
的局部变量,在其生命周期之外使用:
lastPrime->pprime=&addPrime;
lastPrime=&addPrime;
cout << "n:" << lastPrime->pnum <<"\n";
return true;
} // 'lastPrime' is now a dangling pointer because it holds the address
// of 'addPrime' whose lifetime has ended.
要更正,您需要使用prime
动态分配new
。 但,它出现(没有prime
的定义我不确定)代码正在构建遇到的prime
列表。建议使用std::vector<prime>
构建列表并让它为您管理内存。
如果std::vector<prime>
不是一个选项,无论出于何种原因,那么确保prime
的所有实例都是动态分配的,而不是混合动态分配的实例和非动态分配的实例(例如全局two
)因为delete
未动态分配的对象是非法的。
答案 1 :(得分:2)
添加或删除无害代码时出现的问题几乎总是指针错误的结果;有时它会覆盖一些重要的东西,有时它会覆盖一些无关紧要的东西。
在这种情况下,坏指针来自addPrime
的地址并保存。在块addPrime
的末尾消失,指向它的指针变为无效。