Frage

Ich habe ein Spielzeug -Chiffre -Programm, das auf einen Busfehler stoße, wenn er einen sehr langen Schlüssel (ich verwende 961168601842738797, um es zu reproduzieren), was mich verwirrt. Als ich Abschnitte kommentierte, um den Fehler zu isolieren, stellte ich fest, dass er durch diese unschuldige Aussehen für Schleife in meinem Sieb von Eratosthenes verursacht wurde.

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;

}

Manchmal war dies eher ein Segmentierungsfehler als ein Busfehler.

Kann mir jemand helfen zu verstehen, was passiert und wie ich es in Zukunft reparieren/vermeiden kann?

Danke im Voraus!

Ps

Der vollständige Code ist hier verfügbar:

http://pastebin.com/gnesg8eb

War es hilfreich?

Lösung 2

Das Problem ist, dass Sie den Stapel wegblasen.

unsigned long i;
int candidatePrimes[CANDIDATE_PRIMES];

Wenn Candidate_primes groß ist, verändert dies den Stapelzeiger um eine massive Menge. Aber es berührt das Gedächtnis nicht, es nur Passt den Stapelzeiger um eine sehr große Menge an.

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

Dies passt "I" an, was weit zurück im guten Bereich des Stapels ist und es auf Null setzt. Überprüft, ob es <Candidate_Primes ist, was es ist, und somit die erste Iteration durchführt.

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

Dies versucht, die Parameter für "printf" auf den Boden des Stapels zu setzen. BOOM. Ungültiger Speicherort.

Welchen Wert hat Candidate_Primes?

Und du machst du? eigentlich Möchten Sie alle Primzahlen speichern, die Sie testen oder nur die, die passieren? Was ist der Zweck, die Werte 0 bis Candidate_Primes nacheinander in einem Array zu speichern ???

Wenn Sie nur die Primzahlen speichern wollten, sollten Sie eine dynamische Zuordnung verwenden und nach Bedarf ausbauen.

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;
}

Andere Tipps

Ich würde sagen, Ihre VLA ist zu groß für Ihren Stapel, was zu undefiniertem Verhalten führt.

Besser das Array dynamisch zuordnen:

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

Und vergessen Sie nicht free Vor der Rückkehr.

Wenn dies Eratosthenes Sieb ist, dann ist das Array wirklich nur Flags. Es ist verschwenderisch zu verwenden int Wenn es nur 0 oder 1. zumindest verwendet wird char (für Geschwindigkeit) oder kondensiert an einem Bit -Array (für minimale Speicherung).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top