C++-Programm schmiert ab

Hallo, ich hab mich gerade daran gemacht, mein erstes Programm zu schreiben, bei dem ich den Heap benutze. Das scheint aber nicht ganz zu funktionieren, da das Programm ab und zu abschmiert, je nach Anzahl reservierter Variablen.
Ausgabe bei einem Fehler:
Code:
Primfaktoren der Zahl: 444
2 x 2 x 3 x 37
*** glibc detected *** ./primfaktoren: free(): invalid next size (fast): 0x0804a050 ***
======= Backtrace: =========
/lib/libc.so.6[0xb7db13e2]
/lib/libc.so.6(__libc_free+0x7c)[0xb7db2aec]
/usr/lib/gcc/i686-pc-linux-gnu/4.1.1/libstdc++.so.6(_ZdlPv+0x21)[0xb7f49991]
/usr/lib/gcc/i686-pc-linux-gnu/4.1.1/libstdc++.so.6(_ZdaPv+0x1d)[0xb7f499ed]
./primfaktoren(__gxx_personality_v0+0x3c0)[0x8048aa0]
/lib/libc.so.6(__libc_start_main+0xb4)[0xb7d64d64]
./primfaktoren(__gxx_personality_v0+0x51)[0x8048731]
======= Memory map: ========
08048000-08049000 r-xp 00000000 fe:00 5669026    /home/fabian/Coding/primfaktoren
08049000-0804a000 rw-p 00000000 fe:00 5669026    /home/fabian/Coding/primfaktoren
0804a000-0806b000 rw-p 0804a000 00:00 0          [heap]
b7c00000-b7c21000 rw-p b7c00000 00:00 0
b7c21000-b7d00000 ---p b7c21000 00:00 0
b7d4e000-b7d4f000 rw-p b7d4e000 00:00 0
b7d4f000-b7e64000 r-xp 00000000 03:04 858777     /lib/libc-2.5.so
b7e64000-b7e65000 r--p 00115000 03:04 858777     /lib/libc-2.5.so
b7e65000-b7e67000 rw-p 00116000 03:04 858777     /lib/libc-2.5.so
b7e67000-b7e6a000 rw-p b7e67000 00:00 0
b7e6a000-b7e73000 r-xp 00000000 03:04 859597     /usr/lib/gcc/i686-pc-linux-gnu/4.1.1/libgcc_s.so.1
b7e73000-b7e74000 rw-p 00009000 03:04 859597     /usr/lib/gcc/i686-pc-linux-gnu/4.1.1/libgcc_s.so.1
b7e74000-b7e97000 r-xp 00000000 03:04 858276     /lib/libm-2.5.so
b7e97000-b7e99000 rw-p 00022000 03:04 858276     /lib/libm-2.5.so
b7e99000-b7f6d000 r-xp 00000000 03:04 859598     /usr/lib/gcc/i686-pc-linux-gnu/4.1.1/libstdc++.so.6.0.8
b7f6d000-b7f70000 r--p 000d3000 03:04 859598     /usr/lib/gcc/i686-pc-linux-gnu/4.1.1/libstdc++.so.6.0.8
b7f70000-b7f72000 rw-p 000d6000 03:04 859598     /usr/lib/gcc/i686-pc-linux-gnu/4.1.1/libstdc++.so.6.0.8
b7f72000-b7f79000 rw-p b7f72000 00:00 0
b7f89000-b7f8b000 rw-p b7f89000 00:00 0
b7f8b000-b7f8c000 r-xp b7f8b000 00:00 0          [vdso]
b7f8c000-b7fa6000 r-xp 00000000 03:04 858590     /lib/ld-2.5.so
b7fa6000-b7fa7000 r--p 00019000 03:04 858590     /lib/ld-2.5.so
b7fa7000-b7fa8000 rw-p 0001a000 03:04 858590     /lib/ld-2.5.so
bfa37000-bfa4c000 rw-p bfa37000 00:00 0          [stack]
Aborted
Das Programm:
Code:
#include <iostream>
using namespace std;

int main()
{
    int num, e_size;

    do {
        cout << "Primfaktoren der Zahl: ";
        cin >> num;
    } while(num < 0 || num > 5000000);

    // Sieb des Erastotenes
    // Wie groß muss das Sieb sein?
    e_size = num / 2;
    for( int i = e_size; i > 2; i--) {
        if( i % 2 == 0 || i % 3 == 0 || i % 5 == 0 ) {
            e_size--;
        }
    }
    bool *erastotenes = new bool(e_size);

    if( !erastotenes ) {
        cerr << "Es ist nicht genug Speicher verfügbar!";
        return 1;
    }

    // Alle als true markieren
    for(int i = 2; i < num; i++) {
        erastotenes[i] = true;
    }

    bool firstPrimeFactor = true;

    // Alle Vielfachen entfernen
    for(int i = 2; i <= num; i++) {
        // Wenn Primzahl...
        if(erastotenes[i]) {
            // Vielfache entfernen
            if( i % 2 != 0 || i % 3 != 0 || i % 5 != 0 ) {
                for(int k = i; k < num; k += i) {
                    erastotenes[k] = false;
                }
            }

            // Schauen, wie oft Primzahl in gesuchte Zahl reinpasst
            while(num % i == 0) {
                if(firstPrimeFactor) {
                    firstPrimeFactor = false;
                } else {
                    cout << " x ";
                }
                cout << i;
                num /= i;
            }
        }
    }
    cout << endl;

    delete[] erastotenes;
    erastotenes = NULL;
}
 
Original von Eydeet
Code:
    e_size = num / 2;
...
    bool *erastotenes = new bool(e_size);
Ich hab mir den Quelltext, zwar nicht ganz durchgelesen, aber eines ist mir aufgefallen:
Du versuchst dem Boolschen Wert im Heap einen Integer zuzuweisen.
 
haltet mich für einen Anfänger, aber ich hab persönlich was gegen boolean werte. Ich nehm da lieber gleich integer und mach ne 1/0 statt TRUE/FALSE Abfrage. Da gibts auch keine Typecast probleme... Außerdem kann man das dann noch auf VLT oder BESTIMMT erweitern xD
naja, ihr wisst, was ich meine.
 
Das hat aber nix damit zu tun. Wie CLX schon sagte liegt der Fehler bei der Zeile mit
bool* erastotenes = new bool(e_size)

Hier sollte wohl ein Array aus booleans mit der Größe e_size angelegt werden. Stattdessen wurde aber nur eine boolsche variable angelegt und diese mit e_size initialisiert. D.h. die runden Klammern müssen durch eckige ersetzt werden.
Kann aber natürlich sein, dass da noch weitere Fehler drinnen sind, z.B. dass in den Schleifen über Array-Grenzen hinausgeschrieben wird...Hab ich auch nicht genau angeschaut, sieht aber nicht sehr sicher aus was da gemacht wird ;)
 
Danke :D
Ich hab das Programm nochmal komplett neu geschrieben, und jetzt scheint es fehlerfrei zu laufen. Selbst valgrind spuckt keine Fehler mehr aus ;)
Code:
#include <iostream>
#include <cmath>

using namespace std;

bool firstPrime = true;

int factorize( int num, int div ) {
    while( num % div == 0 ) {
        // don't print a multiplicator symbol
        // before first prime
        if( firstPrime )
            firstPrime = false;
        else
            cout << " x ";

        cout << div;
        num /= div;
    }

    return num;
}

int main()
{
    int num, size;

    cout << "Calculate the primefactors of any given value" << endl;

    do {
        cout << "Which number? ";
        cin >> num;
    } while( num < 0 );

    // try most common primes to make
    // erastotenes array smaller
    num = factorize( num, 2 );
    num = factorize( num, 3 );
    num = factorize( num, 5 );

    // are we ready?
    if( num == 1 ) {
        cout << endl;
        return 0;
    }

    size = (int) sqrt(num) + 1;

    // now we need a (very) big array
    // to save every number between 0
    // and the given value.
    bool *erastotenes = new bool[size];
    if( erastotenes == NULL ) {
        cerr << "Error: not enough memory available" << endl;
        return 1;
    }

    // to set every element to 'true',
    // but exclude 0 and 1
    for( int i = 2; i < size; i++ )
        erastotenes[i] = true;

    for( int i = 2; i < size; i++ ) {
        if( erastotenes[i] ) {
            // current number is a prime
            // is our number divisable by it?
            num = factorize( num, i );

            // Are we ready now?
            if( num == 1 )
                break;

            // remove all multiples
            for( int k = i * 2; k < size; k += i )
                erastotenes[k] = false;
        }
    }

    // The number seems to be a prime.
    if( num != 1 )
        factorize(num, num);

    cout << endl;

    // free the reserved space
    delete[] erastotenes;
}
 
Zurück
Oben