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

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

1

31.01.2015, 17:51

C++ Element zu vector hinzufügen und zurück geben...

Guten Abend,

kann mir jemand erklären warum das nicht funktioniert?

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
class Element{
    private:
        int i;

    public:
        Element(const int i):
            i(i){

        }

        int getI(){
            return i;
        }
};

std::vector<Element> elements;

Element* add(const int i){
    elements.push_back(Element(i));
    return &elements.back();
}

int main(int argc, char** args){
    Element* e = add(5);
    Element* e1 = add(6);

    assert("e->i sollte 5 sein.", e->getI() == 5);
    assert("e1->i sollte 6 sein.", e1->getI() == 6);
}

Ausgabe:

Quellcode

1
e->i sollte 5 sein.

Ausgegeben wird dann e->getI() == 0... Der Pointer ist gültig.

Vielen Dank.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

31.01.2015, 17:59

Woher weißt Du, dass der Pointer gültig ist? Die internen Elemente des Vectors ändern ihre Adressen. Das ändert natürlich nicht die Pointer-Adresse Deines Elements.

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
#include <vector>
class Element{
    private:
        int i;

    public:
        Element(const int i):
            i(i){

        }

        int getI(){
            return i;
        }
};

std::vector<Element> elements;

Element* add(const int i){
    elements.push_back(Element(i));
    return &elements.back();
}
#include <iostream>
int main(int argc, char** args){
    Element* e = add(5);
    std::cout<<"e->i sollte 5 sein: "<<e->getI()<<" - "<<&elements[0]<<std::endl;
    Element* e1 = add(6);

    std::cout<<"e->i sollte 5 sein: "<<e->getI()<<" - "<<&elements[0]<<std::endl;
    std::cout<<"e1->i sollte 6 sein: "<<e1->getI()<<" - "<<&elements[1]<<std::endl;
}


Output:
e->i sollte 5 sein: 5 - 0x9e66008
e->i sollte 5 sein: 0 - 0x9e66018
e1->i sollte 6 sein: 6 - 0x9e6601c
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »BlueCobold« (31.01.2015, 18:11)


DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

3

31.01.2015, 18:05

Ah verdammt, stimmt, der vector legt sein array ja neu an :dash:
Problem erkannt, danke :P

4

31.01.2015, 18:08

Wenn man Elemente zum std::vector hinzufügt oder entfernt ist nicht garantiert, dass Zeiger, die auf ein Element darin zeigen, immer noch gültig sind.
Wenn du das willst, benutze std::list. der vector hat gegenüber der liste den Vorteil, dass ein wahlfreier Zugriff immer gleich lang dauert, bei einer 'list' nicht. Dafür dauert bei einer 'list' das einfügen oder entfernen von Elementen immer gleich lange, was bei einem 'vector' nicht so ist.
Edit: natürlich zu spät :p

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

31.01.2015, 18:08

Wie BlueCobold schon sagte: Zeiger (und Iteratoren) auf Elemente eines std::vector sind nur gültig, so lange der std::vector nicht modifiziert wird. Du müsstest also entweder deine Zeiger immer updaten, statt Zeigern Indices verwenden, oder einen anderen Containertyp einsetzen, wie z.B. std::list, wo das kein Problem ist...

Edit: too slow...

6

31.01.2015, 18:42

Ich nehme dann immer ganz gern std::deque, weil man so noch den RandomAccess behält, den ich doch öfter benötige. :vain:

MfG
Check

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

7

31.01.2015, 19:48

Eine Deque hat aber dasselbe Kopier-Problem wie ein Vector. Nur kann man effizienter auch vorn was raus nehmen. Den Bug, um den es in diesem Topic geht, hätte man auch mit einer Deque.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

8

31.01.2015, 20:20

Achso?

MfG
Check

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

31.01.2015, 20:25

Edit: Hmm, habe nochmal cplusplus.com gelesen und ja, kann tatsächlich sein, dass die Elemente nicht kopiert werden. Spannend. Allerdings ist der Zugriff auf ein Element dann wohl nicht mehr O(1), sondern einer Liste ähnlicher. Eine Deque ist also irgendwas zwischen Vector und Liste.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »BlueCobold« (31.01.2015, 20:30)


10

31.01.2015, 20:41

Der Zugriff ist §\mathcal{O}\left(1\right)§. :)

Zitat

The complexity (efficiency) of common operations on deques is as follows:
  • Random access - constant §\mathcal{O}\left(1\right)§
  • Insertion or removal of elements at the end or beginning - amortized constant §\mathcal{O}\left(1\right)§
  • Insertion or removal of elements - linear §\mathcal{O}\left(n\right)§
Quelle: cppreference.com, 31.01.2015

MfG
Check

Werbeanzeige