Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Paulm

Frischling

  • »Paulm« ist der Autor dieses Themas

Beiträge: 69

Wohnort: Baden-Württemberg

Beruf: Schüler

  • Private Nachricht senden

1

27.03.2013, 15:32

vector | Problem mit Iterator nach löschen des Elements

Hallo,

Ich schreibe gerade ein Programm für den Mathematik-Unterricht, welches die Primzahlen in einen Bereich ermitteln soll.
Ich nutze dazu das Siebverfahren des Erastothenes und oben gennante Vektoren. Das Programm soll einen Bereich annehmen und dann die Zahlen in diesem Bereich in einer Liste speichern und auf Teiler überprüfen. Wenn das zu prüfende Vektorelement teilbar ist soll nun das element aus dem Vektor gelöscht werden nun bekomme ich jedoch folgende Fehlermeldung: Expression: vector iterator not decrementable

Es passiert also etwas mit dem Iterator wenn ich das Element lösche wo der Iterator gerade ist.

Hier mein Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>
#include <vector>
#include <math.h>

using namespace std;

//Prototypen
void ausgabe(vector<int> vPrimzahlen);

int main(){
    //Variablen etc.
    vector<int> vPrimzahlen;
    vector<int>::iterator i;

    int aBereich = 0;
    int eBereich = 0;
    int OberGrenze = 0;
    int Differenz = 0;

    cout << "Eingabe des Bereichs: \n\n" << "Anfang: ";
    cin >> aBereich;
    cout << "Ende: ";
    cin >> eBereich;

    //Differenz errechnen
    Differenz = eBereich - aBereich;

    //Alle Zahlen des Bereichs in Vektor schreiben
    for (int k = aBereich; k <= eBereich; k++){
        vPrimzahlen.push_back (k);
    }

    //Vektor ausgeben
    ausgabe(vPrimzahlen);

    //Obergrenze der Teiler errechnen
    OberGrenze = static_cast<int> (sqrt(static_cast<float> (eBereich)));

    //Alle im Vektor gespeicherten Zahlen auf Teiler prüfen
    for (int l = 2; l <= OberGrenze; l++){
        for (i=vPrimzahlen.begin(); i<vPrimzahlen.end(); i++){
            if ((*i)%l == 0){
                vPrimzahlen.erase(i);
                i--;
            }
        }
    }

    ausgabe(vPrimzahlen);
    
    //Verhindern dass das Programm ausläuft
    int test;
    cin >> test;
}

//Ausgabe-Funktion für den Vektor
void ausgabe(vector<int> vPrimzahlen){
    vector<int>::iterator i;
    for (i=vPrimzahlen.begin(); i<vPrimzahlen.end(); i++){
        cout << (*i) << endl;
    }
}

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

27.03.2013, 15:39

Wenn du etwas aus einem std::vector löscht, werden alle Iteratoren in diesen vector ungültig. (Hintergrund: Ein Iterator ist im Prinzip nur ein Pointer in den vector. Wenn du ein Element aus dem vector löscht, wird das interne Array aber evtl. durch ein anderes ersetzt, wodurch alle Zeiger auf den ursprünglichen Speicherbereich ungültig werden.)

Lösung: Schau dir mal an, was std::vector::erase() für einen Rückgabewert liefert... ;)

In dem Fall vermutlich noch bessere Lösung: std::remove_if()

Paulm

Frischling

  • »Paulm« ist der Autor dieses Themas

Beiträge: 69

Wohnort: Baden-Württemberg

Beruf: Schüler

  • Private Nachricht senden

3

27.03.2013, 15:43

Ich habe Zeile 43 nun in i = vector.erase(i)
bekomme aber denselben Fehler

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

4

27.03.2013, 15:45

Wo steht denn dein ++i nun?

Paulm

Frischling

  • »Paulm« ist der Autor dieses Themas

Beiträge: 69

Wohnort: Baden-Württemberg

Beruf: Schüler

  • Private Nachricht senden

5

27.03.2013, 15:58

Ah hatte es vorher mit i++ versucht aber da ging es nicht was ist der unterschied zu ++i?

Paulm

Frischling

  • »Paulm« ist der Autor dieses Themas

Beiträge: 69

Wohnort: Baden-Württemberg

Beruf: Schüler

  • Private Nachricht senden

6

27.03.2013, 16:00

du meinst std::vector::remove_if() oder?

Paulm

Frischling

  • »Paulm« ist der Autor dieses Themas

Beiträge: 69

Wohnort: Baden-Württemberg

Beruf: Schüler

  • Private Nachricht senden

7

27.03.2013, 16:01

doch std::remove_if :D

Cookiezzz

Frischling

Beiträge: 91

Wohnort: Deutschland

Beruf: Schüler

  • Private Nachricht senden

8

27.03.2013, 16:01

Hi,
die Schleife muss so aussehen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
 for (int l = 2; l <= OberGrenze; l++){
        for (i=vPrimzahlen.begin(); i<vPrimzahlen.end();){
            if ((*i)%l == 0){
                i = vPrimzahlen.erase(i);
            }
            else
            {
                i++;
            }
        }
    }


Ansonsten wird der iterator zweimal erhöht, wenn es sich bei der Zahl nicht um eine Primzahl handelt (einmal durch die Schleife und einmal durch das erase()). Das kann dafür sorgen, dass der Iterator bei der letzten Zahl aus dem gültigen Bereich gerät.

EDIT:
Zu langsam...
Der Unterschied ist, dass bei i++ der Wert zuerst zurückgeliefert wird und dann erhöht wird, bei ++i wird erst erhöht. also

C-/C++-Quelltext

1
2
int i = 5;
int a = ++i;//a=6,i=6


C-/C++-Quelltext

1
2
int i = 5;
int a = i++;//a=5,i=6

Paulm

Frischling

  • »Paulm« ist der Autor dieses Themas

Beiträge: 69

Wohnort: Baden-Württemberg

Beruf: Schüler

  • Private Nachricht senden

9

27.03.2013, 17:07

@Cookiezzz Danke für den Hinweis und die Antwort

Paulm

Frischling

  • »Paulm« ist der Autor dieses Themas

Beiträge: 69

Wohnort: Baden-Württemberg

Beruf: Schüler

  • Private Nachricht senden

10

27.03.2013, 17:08

nur so nebenbei kann man geklärte fRagen/threads schliesen?

Werbeanzeige