C++;数组分配分段错误11新手 我是用Robert Sedgewick从C++中学习C++的。现在我正在研究Eratosthenes筛,最大素数有用户指定的上界。当我使用max 46349运行代码时,它会运行并打印出46349之前的所有素数,但是当我使用max 46350运行代码时,会出现分段错误。有人能解释一下原因吗 ./sieve.exe 46349 2 3 5 7 11 13 17 19 23 29 31 ... ./sieve.exe 46350 Segmentation fault: 11

C++;数组分配分段错误11新手 我是用Robert Sedgewick从C++中学习C++的。现在我正在研究Eratosthenes筛,最大素数有用户指定的上界。当我使用max 46349运行代码时,它会运行并打印出46349之前的所有素数,但是当我使用max 46350运行代码时,会出现分段错误。有人能解释一下原因吗 ./sieve.exe 46349 2 3 5 7 11 13 17 19 23 29 31 ... ./sieve.exe 46350 Segmentation fault: 11,c++,memory-management,segmentation-fault,sieve-of-eratosthenes,C++,Memory Management,Segmentation Fault,Sieve Of Eratosthenes,代码: #包括 使用名称空间std; 静态常数int N=1000; int main(int argc,char*argv[]){ int i,M; //将参数解析为整数 if(argv[1]){ M=atoi(argv[1]); } 如果(不是M){ M=N; } //为阵列分配内存 int*a=新的int[M]; //我们是不是记忆犹新? 如果(a==0){ 我知道,问题是声明M是int。当我声明M、J长时,这似乎很好。 < P>我知道,问题是声明M是int。当我声明i、m和j长时,这似乎

代码:

#包括
使用名称空间std;
静态常数int N=1000;
int main(int argc,char*argv[]){
int i,M;
//将参数解析为整数
if(argv[1]){
M=atoi(argv[1]);
}
如果(不是M){
M=N;
}
//为阵列分配内存
int*a=新的int[M];
//我们是不是记忆犹新?
如果(a==0){

我知道,问题是声明M是int。当我声明M、J长时,这似乎很好。

< P>我知道,问题是声明M是int。当我声明i、m和j长时,这似乎很好。

< P>在任何合理的现代C++中,如果分配失败,除非使用Ac++,否则不会从新的NULL指针中获得空指针。不抛出新代码。代码的这一部分不会像您预期的那样工作-您必须捕获调用
new
时可能发出的
std::bad_alloc


你也要声明你的数组索引为类型<代码> siZeSt<<代码> .< /p> < p>在任何合理的现代C++中,如果分配失败,除非使用非投掷的新方法,否则不会从空中得到空指针。代码的那部分不能按你的期望工作,你必须捕获<代码> STD::BADYOLLC/<代码>,这可能是发射的。ted从调用

new
中删除


您还希望将数组索引声明为type
size\t

您在这里有整数溢出:

        for( int j = i; j * i < M; j++ ) {
            a[i * j] = 0;
        }

根据编译器和体系结构的不同,您可能必须使用
long-long
才能获得相同的效果。

此处存在整数溢出:

        for( int j = i; j * i < M; j++ ) {
            a[i * j] = 0;
        }

根据编译器和体系结构的不同,您可能必须使用
long-long
来获得相同的效果。

当您使用调试器运行程序时,您将看到它在以下情况下失败:

a[i * j] = 0;

i*j
溢出并变为负数。这个负数小于
M
,这就是为什么它再次进入循环,然后在访问
a[-2146737495]
时失败的原因。当您使用调试器运行程序时,您将看到它在

a[i * j] = 0;

i*j
溢出并变为负数。这个负数小于
M
,这就是为什么它再次进入循环,然后在访问
a[-2146737495]
时失败的原因。分段错误通常是由于写入超出了分配内存的界限。您应该使用调试器(或添加打印语句)要跟踪程序的进度,以找出发生这种情况的时间点。请注意,如果分配失败,
new
将不会返回
NULL
(除非指定了
nothrow
,此处未指定此项)。它将抛出一个
std::bad_alloc
异常。分段错误通常是由于写入超出分配内存的限制而导致的。您应该使用调试器(或添加打印语句)要跟踪程序的进度,以找出发生这种情况的时间点。请注意,如果分配失败,
new
将不会返回
NULL
(除非指定了
nothrow
,此处未指定此项)。它将抛出一个
std::bad_alloc
异常。我不会指望
long
来做这件事。
long
至少是32位,任何32位的实现都会导致溢出。
long
至少是64位,并且它是C++11的正式部分。如果处理器是32位,那么可能会出现速度问题32位,处理很多64位的数字,但我甚至不知道这会有多大的不同,直到我有时间。正如
NPE
所说,如果
int
是32位,那么
I*j
将溢出,并发生坏事情(比如崩溃)可能会发生。如果
long
有更多的位,那么将
long
设置为64位就可以了,这样
i*j
就不会溢出。我不会指望
long
可以做到这一点。
long
至少是32位,任何32位的实现都会导致溢出。
long-long
至少是64位,而且它是C++11的正式部分。如果处理器是32位的,并且处理大量64位数字,那么速度可能会有问题,但我甚至不知道这会产生多大的差异,直到有时间。正如
NPE
所说,如果
int
是32位的s、 然后,
i*j
将溢出,并发生一些不好的事情(如崩溃)可能会发生。如果
long
有更多的位,那么将
long
设置为64位是可行的,这样
long
就不会溢出。你能推荐一些关于这方面的学习材料吗?我对这门语言完全陌生,还没有接触过内存管理@DavidWilliams,A总是一个好的开始。记住,现代的C++不是像RAIII那样的内存管理,你不需要管理它。你能推荐一些关于这方面的学习材料吗?我对这门语言完全陌生,还没有接触到内存管理。@戴维斯。威廉,A总是一个好的开始。牢记TH。在现代C++中,内存管理不是像RAIII那样,你不必管理它。是迂腐的,我确信你知道,但是技术上不一定是-2146737495。克里斯,这只是GDB的剪切和粘贴。我是个迂腐的人,我相信你知道,但是技术上不一定是-2146737495。克里斯,这只是CU。来自gdb的t和paste。