سؤال

لديّ برنامج تويشور يلعب خطأ في حافلة عندما أعطيت مفتاحًا طويلًا جدًا (أستخدم 961168601842738797 لإعادة إنتاجه) ، وهو ما يحيرني. عندما علقت أقسامًا لعزل الخطأ ، وجدت أنه كان ناتجًا عن هذا المظهر البريء للحلقة في غربال eratosthenes.

unsigned long i;
int candidatePrimes[CANDIDATE_PRIMES];
// CANDIDATE_PRIMES is a macro which sets the length of the array to
// two less than the upper bound of the sieve. (2 being the first prime
// and the lower bound.)

for (i=0;i<CANDIDATE_PRIMES;i++)
{

  printf("i: %d\n", i); // does not print; bus error occurs first

  //candidatePrimes[i] = PRIME;

}

في بعض الأحيان كان هذا خطأ تجزئة بدلاً من خطأ في الحافلة.

هل يمكن لأي شخص مساعدتي في فهم ما يحدث وكيف يمكنني إصلاحه/تجنبه في المستقبل؟

شكرا مقدما!

ملاحظة

الرمز الكامل متاح هنا:

http://pastebin.com/gnesg8eb

هل كانت مفيدة؟

المحلول 2

المشكلة هي أنك تهب المكدس بعيدًا.

unsigned long i;
int candidatePrimes[CANDIDATE_PRIMES];

إذا كان Covilidate_Primes كبيرًا ، فإن هذا يغير مؤشر المكدس بمبلغ ضخم. لكنها لا تلمس الذاكرة فقط يعدل مؤشر المكدس بمقدار كبير جدًا.

for (i=0;i<CANDIDATE_PRIMES;i++)
{

هذا يعدل "أنا" الذي يعود إلى منطقة جيدة من المكدس ، ويضعه على الصفر. يتحقق من أنه <canneridate_primes ، وهو ، وبالتالي يؤدي التكرار الأول.

printf("i: %d\n", i); // does not print; bus error occurs first

هذا يحاول وضع المعلمات لـ "printf" على أسفل المكدس. فقاعة. موقع ذاكرة غير صالح.

ما هي القيمة التي يمتلكها Covilidate_Primes؟

وهل أنت في الحقيقة هل تريد تخزين جميع الأعداد الأولية التي تختبرها أو فقط تلك التي تمر؟ ما هو الغرض من تخزين القيم 0 من خلال Covilident_primes بالتتابع في صفيف ؟؟؟

إذا كان ما أردت فقط تخزين الأعداد الأولية ، فيجب عليك استخدام تخصيص ديناميكي وتنموه حسب الحاجة.

size_t g_numSlots = 0;
size_t g_numPrimes = 0;
unsigned long* g_primes = NULL;

void addPrime(unsigned long prime) {
    unsigned long* newPrimes;
    if (g_numPrimes >= g_numSlots) {
        g_numSlots += 256;
        newPrimes = realloc(g_primes, g_numSlots * sizeof(unsigned long));
        if (newPrimes == NULL) {
            die(gracefully);
        }
        g_primes = newPrimes;
    }
    g_primes[g_numPrimes++] = prime;
}

نصائح أخرى

أود أن أقول أن VLA الخاص بك كبير جدًا بالنسبة لمكدسك ، مما يؤدي إلى سلوك غير محدد.

من الأفضل تخصيص المصفوفة ديناميكيًا:

int *candidatePrimes = malloc(CANDIDATE_PRIMES * sizeof(int));

ولا تنسى ذلك free قبل العودة.

إذا كان هذا هو غربال eratosthenes ، فإن الصفيف هو في الحقيقة مجرد أعلام. إنه أمر مضيء للاستخدام int إذا كان سيعقد فقط 0 أو 1. على الأقل استخدمه char (للسرعة) ، أو تكثيف إلى صفيف صغير (للحصول على الحد الأدنى من التخزين).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top