Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » dynamisches 2d-Array

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ] [ 3 ] [ 4 ]
000
07.09.2011, 08:30 Uhr
~leiti7
Gast


Hallo Leute!

Ich bräuchte mal eure Hilfe und Ideen.

Mein Problem ist das Erstellen eines dynamischen 2d-arrays. Ich habe keine Ahnung wie ich das lösen könnte.
Bei der Programmiersprache bin ich flexibl. Mir ist egal ob die Lösung in C oder C++ ist. Das einfachere wär mir lieber

Kann mir da jemand weiter helfen?

mfg.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
07.09.2011, 09:35 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hi,

naja das funktioniert bei beiden gleich (beim einen halt mit malloc/free und beim anderen mit new/delete - das prinzip bleibt aber gleich)

Es gibt 2 Möglichkeiten: du machst ein "echtes" 2D-Array:


C++:
char **array;
array = new char*[1000]; // erste dimension
for(int i = 0; i < 1000; ++i)
{
   array[i] = new char[2000]; // zweite dimension
}

// zugriff
array[x][y]

// aufräumen
for(int i = 0; i < 1000; ++i)
{
   delete[] array[i];
}
delete[] array;




wie man schon sehen kann, etwas unschön, vor allem weil man keinen zusammenhängenden Speicherbereich erhält.

Was man da oft macht, ist ein 2D-Array zu "simulieren":


C++:
char* array;
array = new char[1000*2000]; // platz für beide dimensionen

// zugriff:
array[y * 1000 + x]

// aufräumen
delete[] array;



Vorteil: Man erhält einen zusammenhängenden Speicherbereich, man alloziiert nur 1x, und nicht x-mal - und man braucht keine schleifen beim alloziieren und aufräumen.

Einzig und allein der Zugriff auf ein Array-Element ist etwas komplizierter, da man sich die Position quasi erst ausrechnen muss.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
07.09.2011, 09:51 Uhr
~leiti7
Gast


Danke erstmal für die 2 Lösungen.

Jetz noch eine Frage:
Muss ich diese dynamischen Arrays in mai deklarieren? Ich habe probiert sie außerhalb von main als globale arrays zu deklarieren, da kommen aber immer zik errors.

Kann man das iwie in verschiedene Funktionen verpacken oder muss Erstellung, Bearbeitung und Löschung in der selben Funktion stattfinden?

mfg.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
07.09.2011, 13:31 Uhr
ao

(Operator)


Deklarieren kannst du das Array auch global.

Die Aufrufe von new und delete und die Zugriffe müssen natürlich innerhalb irgendeiner Funktion erfolgen, die können nicht außerhalb von allem stehen.

Und du kannst auch jeden Schritt in eine eigene Funktion packen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
07.09.2011, 17:32 Uhr
0xdeadbeef
Gott
(Operator)


Ich werf an dieser Stelle mal Boost.Multi-Array in die Runde, das ist dafür ausgesprochen praktisch.

Ansonsten - da wir bei C++ gelandet sind, wo man Operatorüberladung hat, kann man so was doch schön umschiffen. Etwa

C++:
template<typename T>
class array_2d {
public:
  array_2d(std::size_t dim_y, std::size_t dim_x)
    : dim_y_(dim_y), dim_x_(dim_x), data_(new T[dim_x * dim_y]) { }
  ~array_2d() { delete[] data_; }

  std::size_t dim_y() const { return dim_y_; }
  std::size_t dim_x() const { return dim_x_; }

  T       *operator[](std::size_t y)       { return data_ + y * dim_x(); }
  T const *operator[](std::size_t y) const { return data_ + y * dim_x(); }

private:
  // Keine Kopiersemantik
  array_2d(array_2d const &);
  array_2d &operator=(array_2d const &);

  std::size_t dim_y_;
  std::size_t dim_x_;
  T *data_;
};

...

array_2d<double> arr(10, 20);

arr[1][2] = 3.4;


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 07.09.2011 um 17:36 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
08.09.2011, 05:47 Uhr
Lensflare



Ich habe mir speziell dafür auch so eine Klasse geschrieben.
Mit Zusatzschnickschnack wie kopieren, vergleichen und range checks.
Allerdings bin ich nicht auf die Idee gekommen den [] so zu überladen, dass man dann über
arr[d1][d2] zugreifen kann.
Hast du eine Idee wie man das mit [][] UND range checks lösen kann?


DynamicArray2.h

C++:
#ifndef LW_DYNAMIC_ARRAY2_H
#define LW_DYNAMIC_ARRAY2_H

#include <string>
#include <stdexcept>

/**
* 2D Array.
* Size specified at runtime.
*/

template<typename T>
class DynamicArray2 {
protected:
    T* a;
    const int size1;
    const int size2;
    static const std::string indexOutOfBoundsMessage;
    static const std::string sizeMismatchMessage;

protected:

    inline int GetFlatIndex(int index1, int index2) {
        return index1 + index2*size1;
    }

public:

    /**
     * Creates an array with the specified size.
     */

    DynamicArray2(int size1, int size2) : size1(size1), size2(size2) {
        this->a = new T[size1 * size2];
    }

    /**
     * Creates this array as a copy of the specified array.
     */

    DynamicArray2(const DynamicArray2<T>& v) : size1(size1), size2(size2) {
        if (this != &v) {
            this->a = new T[size1 * size2];

            for (int j = 0; j < size2; ++j) {
                for (int i = 0; i < size1; ++i) {
                    const int index = GetFlatIndex(i, j);
                    this->a[index] = v.a[index];
                }
            }
        }
    }

    /**
     * Deletes this array and all internal created data.
     */

    virtual ~DynamicArray2() {
        delete[] a;
    }

    /**
     * Gets the pointer to the 1D Array containing all elements.
     */

    inline T* GetData() {
        return a;
    }

    /**
     * Returns the first dimension of this array.
     */

    inline int Size1() {
        return size1;
    }

    /**
     * Returns the second dimension of this array.
     */

    inline int Size2() {
        return size2;
    }

    /**
     * Returns the value referenced by the specified indeces.
     */

    inline const T & operator()(int index1, int index2) const {
        if (index1 >= 0 && index1 < size1 && index2 >= 0 && index2 < size2) {
            return a[GetFlatIndex(index1, index2)];
        }

        throw std::out_of_range(indexOutOfBoundsMessage);
    }

    /**
     * Returns or sets the value referenced by the specified indeces.
     */

    inline T & operator()(int index1, int index2) {
        if (index1 >= 0 && index1 < size1 && index2 >= 0 && index2 < size2) {
            return a[GetFlatIndex(index1, index2)];
        }

        throw std::out_of_range(indexOutOfBoundsMessage);
    }

    /**
     * Returns the value referenced by the specified flat index.
     */

    inline const T & operator[](int flatIndex) const {
        if (flatIndex < size1 * size2 && flatIndex >= 0) {
            return a[flatIndex];
        }

        throw std::out_of_range(indexOutOfBoundsMessage);
    }

    /**
     * Returns the value referenced by the specified flat index.
     */

    inline T & operator[](int flatIndex) {
        if (flatIndex < size1 * size2 && flatIndex >= 0) {
            return a[flatIndex];
        }

        throw std::out_of_range(indexOutOfBoundsMessage);
    }

    /**
     * Compares this array with the specified array, value by value.
     * Returns true if equal.
     */

    bool operator==(const DynamicArray2<T>& v) const {
        if (this->size1 == v.size1 && this->size2 == v.size2) {
            for (int j = 0; j < size2; ++j) {
                for (int i = 0; i < size1; ++i) {
                    const int index = GetFlatIndex(i, j);
                    if (this->a[index] != v.a[index]) {
                        return false;
                    }
                }
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * Compares this array with the specified array, value by value.
     * Returns true if not equal.
     */

    bool operator!=(const DynamicArray2<T>& v) const {
        if (this->size1 == v.size1 && this->size2 == v.size2) {
            for (int j = 0; j < size2; ++j) {
                for (int i = 0; i < size1; ++i) {
                    const int index = GetFlatIndex(i, j);
                    if (this->a[index] != v.a[index]) {
                        return true;
                    }
                }
            }
            return false;
        } else {
            return true;
        }
    }

    /**
     * Assignes the specified array to this array, value by value.
     * Throws exception if the sizes of the arrays are not equal.
     */

    DynamicArray2<T> & operator=(const DynamicArray2<T>& v) {
        if (this != &v) {
            if (this->size1 != v.size1 || this->size2 != v.size2) {
                throw std::range_error(sizeMismatchMessage);
            }

            for (int j = 0; j < size2; ++j) {
                for (int i = 0; i < size1; ++i) {
                    const int index = GetFlatIndex(i, j);
                    this->a[index] = v.a[index];
                }
            }
        }

        return *this;
    }
};

template<typename T>
const std::string DynamicArray2<T>::indexOutOfBoundsMessage = "Array index out of range";

template<typename T>
const std::string DynamicArray2<T>::sizeMismatchMessage = "Array size mismatch";

#endif //LW_DYNAMIC_ARRAY2_H




Main.cpp

C++:
#include "DynamicArray2.h"

int main() {
    DynamicArray2<double> arr(10, 20);
    arr(1, 2) = 3.4;

    return 0;
}


--
Wenn das Gehirn so einfach wäre, dass wir es verstehen könnten, wären wir so einfach, dass wir es nicht verstehen könnten.
(Emerson Pugh Trost)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
08.09.2011, 07:16 Uhr
~leiti7
Gast


habe es nun auf diese weise versucht zu lösen:



Zitat von Benutzer:

char **array;
array = new char*[1000]; // erste dimension
for(int i = 0; i < 1000; ++i)
{
array[i] = new char[2000]; // zweite dimension
}

// zugriff
array[x][y]

// aufräumen
for(int i = 0; i < 1000; ++i)
{
delete[] array[i];
}
delete[] array;



jedoch verursachte dies folgenden Fehler beim ausführen des Programms:


First-chance exception in dynamic2d.exe: 0xC0000005: Access Violation.


kann mir da jemand helfen und vll sagen was falsch sein könnte?

mfg.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
08.09.2011, 09:42 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


wenn du uns deinen code zeigen könntest, könnten wir dir auch helfen
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
08.09.2011, 10:22 Uhr
~leiti7
Gast



Zitat von FloSoft:

wenn du uns deinen code zeigen könntest, könnten wir dir auch helfen



mein code ist viel zu lang um ihn hier zu posten.

könnte mir nicht jemand so nen tipp geben? hängt dieser fehler mit der speicher reservierung zusammen? wenn nein mit was könnte er zusammenhängen?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
08.09.2011, 10:49 Uhr
ao

(Operator)


0xC0000005: Access Violation, das heißt, dein Programm greift ins Klo. Es versucht, auf einen Speicherbereich zu schreiben, der ihm nicht gehört. Oder daraus zu lesen, das kann man hier nicht erkennen.

Gern gemachte Fehler:
* Index über- oder unterschritten
* Uninitialisierte Zeiger verwendet
* Die Allokierung hat nicht geklappt, der Zeiger wird trotzdem verwendet (ist hier aber unwahrscheinlich, erstens sind die Größen nicht so astronomisch, zweitens hättest du eine bad_alloc-Exception ignorieren müssen, um bis hier zu kommen).


Zitat:
könnte mir nicht jemand so nen tipp geben?

"First chance exception" - das heißt, du bist im Debugger von Visual Studio? Dann guck dir doch mal den Call-Stack an, dann siehst du, wo es hakt.

Falls du noch nie mit dem Debugger gearbeitet hast, ist jetzt der Zeitpunkt, es zu lernen. Starte dein Programm nicht mit F5, sondern mit F10 und arbeite dich schrittweise durch und sieh dir an, was passiert.


Zitat:
mein code ist viel zu lang um ihn hier zu posten.

Wenn du mit dem Debugger nicht weiterkommst, dann kürz den Code so weit wie möglich (d.h. möglichst viel rausschmeißen, so dass der Fehler noch auftritt).
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ] [ 3 ] [ 4 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: