C++内存指针练习中的未知崩溃 我最近写了一个程序,帮助我理解C++中的内存指针的基本知识,我选择了一个简单的素数查找器。
我终于成功了。很感谢调试 我让它运行,看看它走了多远,它到达了815389,我的长篇大论告诉我是65076,我的应用程序崩溃了。我能想到的一件事是我的整数溢出了,所以我把它们改成了长整数,它被卡在了同一个地方 有人能解释一下是什么限制导致了这种情况吗 组件:WinVista 64位家庭高级版,6GB ram AMD 4800+X2 程序在使用4664K内存时崩溃 资料来源:C++内存指针练习中的未知崩溃 我最近写了一个程序,帮助我理解C++中的内存指针的基本知识,我选择了一个简单的素数查找器。,c++,pointers,crash,C++,Pointers,Crash,我终于成功了。很感谢调试 我让它运行,看看它走了多远,它到达了815389,我的长篇大论告诉我是65076,我的应用程序崩溃了。我能想到的一件事是我的整数溢出了,所以我把它们改成了长整数,它被卡在了同一个地方 有人能解释一下是什么限制导致了这种情况吗 组件:WinVista 64位家庭高级版,6GB ram AMD 4800+X2 程序在使用4664K内存时崩溃 资料来源: #include <cstdlib> #include <iostream> \\\\(Bac
#include <cstdlib>
#include <iostream>
\\\\(Backslashes added for readability)
using namespace std;
long number;
long numnum;
class num;
class num {
public:
long i;
void check();
bool nxt;
num* nxtnum;
};
void num::check() {
if (number % i != 0) {
if (nxt == true) {
(*nxtnum).check();
} else {
nxtnum = new num();
(*nxtnum).i = number;
numnum++;
cout << numnum << ":" << number << ", ";
nxt = true;
};
};
};
int main(long argc, char *argv[]){
numnum = 1;
cout << numnum << ":" << 2 << ", ";
num two;
two.i = 2;
for (number = 3; 1<=1000001; number++) {
two.check();
};
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
};
不管用户名是什么,它只是我使用的一个别名,这样我就可以用谷歌跟踪我所有的帖子了?我看到这个检查是递归的。我猜测two.nxt没有初始化。在C语言中,基本数据类型没有初始化,这意味着它们具有它现在占用的内存中的值。这意味着更可能的情况是,在main中,two.nxt=true,这会导致在无效指针上运行检查。尝试显式地将其设置为false,看看这是否适用于您
[编辑]如果这是一个问题,更重要的初始化是在检查中分配新的num时。我可以看到几个问题: 您正在分配大量NUM,但没有检查std::bad_alloc异常。您可能只是内存不足。。。 如果nxtnum是,您不会在任何地方进行检查!=0,即使我认为这样做是安全的,因为您解除引用它所保护的唯一位置。然而,这并不是一个很好的练习。 正如Sean Edwards提到的,num类没有构造函数,因此新创建的num的成员中充满了几乎随机的垃圾。随机垃圾可能包括nxt被设置为非零值。我将添加以下构造函数,为其提供一组安全默认值: num::num:i0,nxtfalse,nxtnum0{} 您并不需要布尔值,我只需要检查nxtnum是否为非零 正如Jeff Yates所说,由于递归函数嵌套得太深,您可能会遇到堆栈溢出,但它看起来不会递归到那么深。
肖恩是对的,2.nxt从来没有初始化过。事实上,num.nxt从未对num的任何实例进行初始化。如果类变得更健壮,则成员nxt是不必要的。可以改用nxt指针:
class num
{
private:
long i;
num *nxtnum;
public:
num (long value) : i (value), nxtnum (0) { }
void check ()
{
if (number % i != 0)
{
if (nxtnum)
{
nxtnum->check ();
}
else
{
nxtnum = new num (number);
cout << ++numnum << ":" << number << ", ";
}
}
};
当然,递归性可能是主要原因,初始化问题隐藏在您可能正在运行调试构建时。将递归形式转换为迭代形式只是一个练习。顺便说一句,如果您使用的是Microsoft编译器,则针对x64时int和long的大小相同。在主函数中还有一个无限循环,因为1总是我已经让它工作了,谢谢Skizz
#include <cstdlib>
#include <iostream>
#include <windows.h>
using namespace std;
long number;
long numnum;
class num;
num *two;
num *nn;
num *bre;
class num
{
private:
long i;
num *nxtnum;
public:
num (long value) : i (value), nxtnum (0) { }
void *check ()
{
if (number % i != 0)
{
if (nxtnum)
{
//nxtnum->check ();
nn = nxtnum;
}
else
{
nxtnum = new num(number);
cout << ++numnum << ":" << number << ", ";
nn = bre;
}
}else{nn=bre;}
}
};
int main(long argc, char *argv[])
{
numnum = 1;
cout << numnum << ":" << 2 << ", ";
two = new num(2);
nn=two;
for (number = 3; 1<=1000001; number++) {
while (nn!=bre){
nn->check();
Sleep(0);
}
nn=two;
};
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
};
对于那些感兴趣的人,我假设这个问题是个笑话:我也是,但以防万一,我会回答的递归总是可以转化为迭代。好吧,在这种情况下,我会更关注Jeff Yates的答案:+我感谢肖恩发现了这一点。即使这没有解决崩溃问题,Sean绝对正确,您使用的是two.nxt,而没有对其进行初始化,因此它的行为可能会因编译而异,甚至会因运行而异。顺便说一句,作为单独nxt数据成员的替代方案,C/C++程序员通常只是在列表末尾将nxtnum设置为NULL,然后进行测试。它必须递归到多深?谢谢,我从您的代码中学习了一些东西,并将尝试使其正常工作。是的,我想看看它会有多高。您可以始终将中间条件保留为空,或者将其设置为真。嘿!看起来您正在使用Dev-C++。。。猜猜我怎么知道?