K
Basti153, statt mit "rohen Arrays" à la int[6] kannst du auch mit array<int,6> aus dem std -Namensraum arbeiten. Das gibt es seit C++11. Es bietet Dir typischerweise – zumindest mit g++/libstdc++ – auch einen netten Debug-Modus an, der dir dann solche Fehler wie ungültige Indizes schon viel früher abfängt. Versuche am besten rohe Arrays und Zeiger zu vermeiden. Wie du gemerkt hast, ist das fehleranfällig.
Statt Zeiger bräuchten wir eigentlich so etwas wie eine standardisierte Familie von array_view -Typen, die auch einen solchen Debug-Modus anbieten. Denn oft sieht man ja Funktionen, die Zeiger + Länge übergeben bekommen. Das sollte IMHO ein einziger Parameter sein. In anderen Sprachen gibt's das ja auch oft unter dem Namen "slice". Ich habe mir so etwas selbst nachgebaut (allerdings ohne "checked iterators"). Dieses Klassentemplate erlaubt dann z.B. folgenden Code:
void anzeigen(slice<const int> s) {
while (s) {
std::cout << s.shift_ref() << std::endl; // quasi *ptr++ Äquivalent
}
}
int main() {
int feld[] = {1,2,3,4,5};
std::vector<int> vektor = {1,2,3,4,5,6,7,8,9};
anzeigen(feld); // 1 bis 5
anzeigen(vektor); // 1 bis 9
anzeigen(const_all_of(vektor).slice_from(4)); // 5 bis 9
}
Ich weiß, dass ich nicht perfekt bin, also überlasse ich das "Indexgeprüfe" lieber slice<T> im Debugmodus.
Warum keine Iteratoren? Weil mich Iteratoren, zumindest das, was man in C++ darunter versteht, nerven! Lineares Speicherlayout kommt zudem bei mir recht oft vor. Mein slice ist quasi ein Spezialfall einer "Alexandrescu-Range" für lineares Elementen-Layout. Was die letzten Ideen von Eric Niebler in der Richtung angehen, da bin ich leider nicht auf dem aktuellen Stand.
Und weil das so schön zum Thema Speichersicherheit passt hier noch ein Tipp: Rust 1.0.0-beta.2 ist jetzt veröffentlicht worden. SCNR