ما الذي يسبب خطأ تجزئة؟
-
21-09-2019 - |
سؤال
لقد حاولت كتابة برنامج يحدد ما إذا كان الرقم مسبقًا أم لا. لقد استندت إلى غربال إراتوستينيس. على أي حال ، يعمل برنامجي للأعداد الصغيرة (15485863 يعمل) ، ولكن إذا استخدمت أعدادًا كبيرة (على سبيل المثال. 17485863) ، أتلقى خطأ تجزئة. أنا أستخدم الطويلات الطويلة غير الموقعة ولا أعتقد أنني تجاوزت أقصى قيمتها. أنا فقط لا أرى ما قمت به خطأ. شكرا لتقديمك المساعده!
#include <iostream>
#include <limits>
using namespace std;
bool soe (unsigned long long);
int main (void)
{
unsigned long long x = 17485863;
bool q = soe(x);
cout << x << " is ";
if(q)
cout << "prime." << endl;
else
cout << "not prime." << endl;
return 0;
}
bool soe(unsigned long long input)
{
unsigned long long arrayLength = input%2 + input/2;
unsigned long long index = 2;
unsigned long long greatestMult = 0;
bool array[arrayLength];
array[0] = true; //ignore true values in the array
array[1] = true;
do{
array[index] = false;
}while(++index < arrayLength);
index = 2;
do
{
if(input%index != 0)
{
greatestMult = input/index;
while(index*greatestMult > arrayLength)
greatestMult--;
do
{
array[index*greatestMult] = true;
}while(--greatestMult > 0);
do
{
if(!array[index])
break;
}while(++index < arrayLength);
}
else
{
cout << endl << input << " is divisble by " << index << endl;
return false;
}
}while(index < arrayLength);
return true;
}
المحلول
على الخط 24 لديك: bool array[arrayLength];
لا يمكنك إعلان صفيف على المكدس مثل هذا. يتم تحطيم البرنامج على الخط 29. تحتاج إلى إعلان هذا على الكومة باستخدام New/Delete ؛
شيء بهذا المعنى (قد يكون لدي تسرب أو اثنين هناك ، لكنك تحصل على الفكرة) ؛
//Beginning on Line 28
bool *array = new bool[arrayLength];
array[0] = true; //ignore true values in the array
array[1] = true;
do{
array[index] = false;
}while(++index < arrayLength);
index = 2;
do
{
if(input%index != 0)
{
greatestMult = input/index;
while(index*greatestMult > arrayLength)
greatestMult--;
do
{
array[index*greatestMult] = true;
}while(--greatestMult > 0);
do
{
if(!array[index])
break;
}while(++index < arrayLength);
}
else
{
cout << endl << input << " is divisble by " << index << endl;
delete [] array;
return false;
}
}while(index < arrayLength);
delete [] array;
return true;
}
انتاج |
g++ -g test.cpp
gdb ./a.out
...clipped...
(gdb) run
Starting program: /Users/nextraztus/a.out
Reading symbols for shared libraries ++. done
17485863 is divisble by 3
17485863 is not prime.
Program exited normally.
(gdb)
نصائح أخرى
يرجى ملاحظة أنه لا يوجد طول طويل ولا استخدام المتغيرات إلى المصفوفات التلقائية للبعد جزء من C ++ - فهي امتدادات توفرها GCC ويجب عدم استخدامها إذا كانت قابلية النقل مشكلة.
لمعالجة مشكلتك ، أبعاد صفيف مثل هذا:
bool array[arrayLength];
سوف يتسبب في تجاوز سعة مكدس (وبالتالي خطأ SEG) إذا كانت قيمة الطول كبيرة جدًا. استخدم ناقل STD :: بدلاً من ذلك ، ولكن كن على علم بأن الذاكرة ليست مورد لا حصر له.
من الممكن أن يكون الفهرس*الأعظم مساوياً لـ ArrayLength ، حتى تتمكن من الكتابة فوق العنصر الأخير بعد نهاية الصفيف.
يمكن أيضًا تخصيص المصفوفات الكبيرة على المكدس مثل ذلك مشكلة اعتمادًا على نظام التشغيل. ستقوم بعض الأنظمة بتوسيع المكدس كثيرًا ، ولن يتمكن البعض الآخر من ذلك.