Array in Klasse mit new deklarieren



  • Ich stehe vor dem Problem, dass ich ein Array wie z.B:

    double (*m_pA)[SIZEDOE] = new double[SIZEDOE][SIZEDOE]; // AmplitudeDOE
    ...
    delete m_pA;

    in einer Klasse verpacken möchte.

    Dazu habe ich in die Klasse in die Header Datei den Pointer geschrieben:

    class AdaptiveAlgorithm
    {
    public:
    	AdaptiveAlgorithm(void);
    	~AdaptiveAlgorithm(void);
    
    private:
    	double* m_A; // AmplitudeDOE
    };
    

    und in den Konstruktor bzw Destruktur den Rest:

    #include "AdaptiveAlgorithm.h"
    
    /* Konstruktor */
    AdaptiveAlgorithm::AdaptiveAlgorithm(void)
    {
    	(*m_pA)[SIZEDOE] = new double[SIZEDOE][SIZEDOE]; // AmplitudeDOE
    }
    
    /* Destruktor */
    AdaptiveAlgorithm::~AdaptiveAlgorithm(void)
    {	 
    	delete m_pA;
    }
    

    Das jedoch funktioniert überhaupt nicht.
    Im Destruktor wird m_pA weder als bekannt noch als Pointer erkannt.

    Wie macht man es also richtig ?

    Matthias



  • Hi,

    1.)

    pospiech schrieb:

    ...

    class AdaptiveAlgorithm
    {
    ...	double* m_A; // AmplitudeDOE
    ...	(*m_pA)[SIZEDOE] = new double[SIZEDOE][SIZEDOE]; // AmplitudeDOE
    ...	delete m_pA;
    

    ...

    Du musst Dich schon entscheiden, wie Deine Variable heißen soll ... mit p oder ohne.

    2.)
    Im Ctor schreibst Du

    (*m_pA)[SIZEDOE] = ...
    

    Damit dereferenzierst Du den Pointer. Wohin zeigt der denn ? Liegt da etwas, das Du dereferenzieren kannst ?
    In Deinem obigen Code jedenfalls nicht. Du Dereferenzierst sogar doppelt: Einmal mit * und einmal mit [] ...

    • das geht mit einem double* gar nicht (nur einmal),
    • mit einem double** bekämst Du nach doppelter Dereferenzierung einen double ... und dem kannst Du nicht per new einen Zeiger zuweisen.

    Wenn Du tatsächlich 2 Dimensionen verwenden möchtest, muß Dein Attribut vom Typ double** sein und Du musst

    • zuerst ein Array von Zeigern allozieren
    double** m_A = new double* [SIZE1];
    
    • ... und danach für jeden Zeiger ein entsprechendes Feld:
    for(int i=0; i<SIZE1; ++i) {
        m_A[i] = new (double)[SIZE2];
    }
    

    (Noch einfacher hättest Du es mit einem vector<vector<double> > m_A;)

    3.) Wo immer Du new[] verwendest (und das versuchst Du) musst DU delete[] verwenden, sonst gibt's Speicherlecks (oder undefiniertes Verhalten ?).

    4.) Warum Arrays, wenn man STL-Container wie std::vector haben kann, die einem den ganzen Krempel abnehmen können.... 😃

    Gruß,

    Simon2.



  • Simon2 schrieb:

    Du musst Dich schon entscheiden, wie Deine Variable heißen soll ... mit p oder ohne.

    mein Fehler. Das löst mein Prolem aber in keiner Weise.

    Simon2 schrieb:

    Im Cto schreibst Du

    (*m_pA)[SIZEDOE] = ...
    

    Damit dereferenzierst Du den Pointer. Wohin zeigt der denn ? Liegt da etwas, das Du dereferenzieren kannst ?

    Ich verstehe was du meinst, aber suche nach dem korreten Code - den den kenne ich ja nicht.

    Simon2 schrieb:

    3.) Wo immer Du new[] verwendest (und das versuchst Du) musst DU delete[] verwenden, sonst gibt's Speicherlecks (oder undefiniertes Verhalten ?).

    Jetzt verstehe ich nur noch Bahnhof.
    Ich möchte in einer Klasse ein Array dynamisch deklarieren. Es soll mit dem Destruktor der Klasse wieder zuerstört werden, und im Konstruktor (oder wo auch immer) aufgebaut.

    Wie macht man das? Ich suche einen einfachen Beispielcode für eine mehrdimensionale Matrix.

    Simon2 schrieb:

    4.) Warum Arrays, wenn man STL-Container wie std::vector haben kann, die einem den ganzen Krempel abnehmen können.... 😃

    Was hilft mir ein STL Vector wenn ich sowieso ein 2 Dimensionales Array benötige? Abgesehen davon, dass ich von STL nicht den blassesten Schimmer habe.

    Das mein Code vermutlich grottenfalsch ist wundert mich nicht, da ich überhaupt nicht weiß wie es gehen sollte. Mir ist daher mit einem richtigen Beispiel für ein dynamisches 2D-Array in einer Klasse am meisten geholfen.

    Matthias



  • Vielleicht schaust du einfach mal in die FAQ zum Thema dynamische mehrdimensionale Arrays



  • Braunstein schrieb:

    Vielleicht schaust du einfach mal in die FAQ zum Thema dynamische mehrdimensionale Arrays

    Also so:

    int (*pArr)[5] = 0;
        pArr = new int[2][5];
        pArr[0][0] = 42;
        delete [] pArr;
    

    nur dass ich die erste Zeile in den header, und die zweite in den Konstruktor und die letzte in den Destruktor schreibe.

    Danke,
    Matthias



  • pospiech schrieb:

    ...
    Ich verstehe was du meinst, aber suche nach dem korreten Code - den den kenne ich ja nicht. ...

    Naja, den habe ich schon geschrieben:

    Simon2 schrieb:

    ...
    Wenn Du tatsächlich 2 Dimensionen verwenden möchtest, muß Dein Attribut vom Typ double** sein und Du musst

    • zuerst ein Array von Zeigern allozieren
    double** m_A = new double* [SIZE1];
    
    • ... und danach für jeden Zeiger ein entsprechendes Feld:
    for(int i=0; i<SIZE1; ++i) {
        m_A[i] = new double [SIZE2];
    }
    

    (Noch einfacher hättest Du es mit einem vector<vector<double> > m_A;)
    ...

    pospiech schrieb:

    ...

    Simon2 schrieb:

    3.) Wo immer Du new[] verwendest (und das versuchst Du) musst DU delete[] verwenden, sonst gibt's Speicherlecks (oder undefiniertes Verhalten ?).

    Jetzt verstehe ich nur noch Bahnhof.

    Du schreibst (vollkommen zurecht)

    ... new [i]...irgendwas...[/i] [b][u][[/u][/b] [i]...irgendwas...[/i] [b][u]][/u][/b]
    

    In C++ gibt es zwei unterscheidliche Operatoren:

    • new
    • new[]

    ... und die tun etwas unterschiedliches. Ersterer holt sich Speicher für und erzeugt dahin ein Objekt (Ein Ctor-Aufruf).
    Zweiterer tut das für mehrere Objekte => er ruft mehrere Mal den Ctor der Klasse auf (für jedes Objekt einmal)

    Dementsprechend gibt es auch zwei unterschiedliche "Aufräumoperatoren":

    • delete
    • delete[]

    und da muß eben der Passende aufgerufen werden (also z.B. delete[] p; ) ... allein schon, damit tatsächlich für jedes Objekt der Destruktor aufgerufen wird.

    pospiech schrieb:

    ...
    Was hilft mir ein STL Vector wenn ich sowieso ein 2 Dimensionales Array benötige?......

    Ein vector<vector<double> > (wie oben schon erwähnt) kümmerst sich "selbst" darum, dass genug Speicher da ist und nimmt Dir die Verwaltung davon ab.
    In Deinem Beispiel muß Deine AdaptiveAlgorithm-Klasse ja irgendetwas machen, wenn plötzlich eine Zeile oder Spalte hinzukommen soll....und zwar eine Menge new/copy/delete-Zeug. Mit vector reicht ein resize() (was ja an und für sich schon rect sprechend in dem Zusammenhang ist)...

    pospiech schrieb:

    ...
    Mir ist daher mit einem richtigen Beispiel für ein dynamisches 2D-Array in einer Klasse am meisten geholfen.
    Matthias

    Ich glaube, Dir ist am meisten wirklich geholfen, wenn Du verstehst, wie man das tust - und dazu versuche ich Dir zu helfen. 🙂

    Gruß,

    Simon2.



  • pospiech schrieb:

    Braunstein schrieb:

    Vielleicht schaust du einfach mal in die FAQ zum Thema dynamische mehrdimensionale Arrays

    Also so:

    int (*pArr)[5] = 0;
        pArr = new int[2][5];
        pArr[0][0] = 42;
        delete [] pArr;
    

    nur dass ich die erste Zeile in den header, und die zweite in den Konstruktor und die letzte in den Destruktor schreibe.

    Danke,
    Matthias

    Dein Problem könnte (wird) sein, dass in diesem Beispiel die 5 zur Compilezeit bekannt sein muß....
    Vielleicht helfen Dir noch templates ... aber spätestens, wenn diese Größe von einem Benutzer eingegeben werden soll, geht auch das nichtmehr.

    Du findest wirklich

    #include <vector>
    using namespace std;
    int main()
    {
        const int FirstDim = 3;
        const int SecDim = 2;
        vector< vector<int> > My2DimArr(FirstDim);
        for (int i = 0; i < FirstDim; i++)
            My2DimArr[i].resize(SecDim);
       
        My2DimArr[1][1] = 42;
    }
    

    zu kompliziert ?
    Hier können FirstDim und SecDim zur Laufzeit eingegeben werden....

    Oder in Deinen OriginalCode eingebaut:

    class AdaptiveAlgorithm
    {
    public:
        AdaptiveAlgorithm(size_t FirstDim, size_t SecDim) : m_A(FirstDim) {
            for(size_t i = 0; i < FirstDim; i++) m[i].resize(SecDim);
        }
        // Dtor braucht's gar nicht
    private:
        vector<vector<double> > m_A; // Leerzeichen zwischen > > ist wichtig !
    };
    

    Gruß,

    Simon2.



  • pospiech schrieb:

    class AdaptiveAlgorithm
    {
    public:
    	AdaptiveAlgorithm(void);
    	~AdaptiveAlgorithm(void);
    
    private:
    	double* m_A; // AmplitudeDOE
    };
    

    und in den Konstruktor bzw Destruktur den Rest:

    #include "AdaptiveAlgorithm.h"
    
    /* Konstruktor */
    AdaptiveAlgorithm::AdaptiveAlgorithm(void)
    {
    	(*m_pA)[SIZEDOE] = new double[SIZEDOE][SIZEDOE]; // AmplitudeDOE
    }
    
    /* Destruktor */
    AdaptiveAlgorithm::~AdaptiveAlgorithm(void)
    {	 
    	delete m_pA;
    }
    

    Matthias

    class AdaptiveAlgorithm
    {
    public:
    	AdaptiveAlgorithm(void);
    	~AdaptiveAlgorithm(void);
    
    private:
    	double (*m_pA)[SIZEDOE];
    
    #include "AdaptiveAlgorithm.h"
    
    /* Konstruktor */
    AdaptiveAlgorithm::AdaptiveAlgorithm(void)
    {
    	m_pA = new double[SIZEDOE][SIZEDOE]; // AmplitudeDOE
    }
    
    /* Destruktor */
    AdaptiveAlgorithm::~AdaptiveAlgorithm(void)
    {	 
    	delete[] m_pA;
    }
    

    mfg



  • pospiech schrieb:

    Was hilft mir ein STL Vector wenn ich sowieso ein 2 Dimensionales Array benötige?

    Ein Vector hilft dir sehr viel. Denn dafür wurde er entwickelt. Der ist ganz bestimmt nicht aus Jux und Dollerei in der Standardbibliothek drin.

    pospiech schrieb:

    Abgesehen davon, dass ich von STL nicht den blassesten Schimmer habe.

    Dann solltest du C++ lernen. Die Standardbibliothek gehört zu den C++-Basics.



  • [quote="Artchi"]

    pospiech schrieb:

    pospiech schrieb:

    Abgesehen davon, dass ich von STL nicht den blassesten Schimmer habe.

    Dann solltest du C++ lernen. Die Standardbibliothek gehört zu den C++-Basics.

    Das würde ich gerne. Derzeit benötige ich C++ für die Promotion und bin froh wenn ich C++ ausreichend bis zum Ende der Promotion kann. Dann aber sind die Programme fertig und vermutlich in keinem guten C++ geschrieben - was ich aber nicht ändern kann, denn sonst müßte ich erstmal ein halbes Jahr investieren und nur C++ lernen... (ich bin kein Informatiker)

    Matthias



  • pospiech schrieb:

    Artchi schrieb:

    pospiech schrieb:

    Abgesehen davon, dass ich von STL nicht den blassesten Schimmer habe.

    Dann solltest du C++ lernen. Die Standardbibliothek gehört zu den C++-Basics.

    Das würde ich gerne. Derzeit benötige ich C++ für die Promotion und bin froh wenn ich C++ ausreichend bis zum Ende der Promotion kann. Dann aber sind die Programme fertig und vermutlich in keinem guten C++ geschrieben - was ich aber nicht ändern kann, denn sonst müßte ich erstmal ein halbes Jahr investieren und nur C++ lernen... (ich bin kein Informatiker)

    Matthias

    Das verstehe ich - wer kann es sich schon leisten, "hauptberuflich C++ zu lernen" ? 😉

    Allerdings mußt Du überlegen, ab wann Dich ein "irgendwie Hinfrickeln" mehr kostet als es einbringt. Vermutlich wird das hier nicht das letzte Stückchen Source sein, was Du für Deine Arbeit basteln musst ... und wenn Du Dich jetzt ein wenig in die STL reinkniest, kann Dir das bei zukünftigen (evtl. schwereren) Aufgaben sehr viel Zeit sparen.

    Konkret: Wenn Du jetzt ein wenig vector ansiehst, brauchst Du Dich vermutlich nie mehr mit

    • new[]/delete[],
    • seltsamen Arraydefinitionen ("double (*m)[10]" ist nicht immer sprechend) und
    • -Funktionsübergaben (Arraydimensionen übergeben ?),
    • den seltsamen Zusammehang von Pointern und Arrays,
    • verändernden Dimensionen (was passiert eigentlich, wenn Du plötzlich eine 3D-Matrix brauchst ?) etc. rumschlagen

    Ich wette, den Einsatz eines vectors hättest Du in derselben Zeit hinbekommen, die Du bisher mit der richtigen Array-Syntax verbraten hast.... 😃

    Gruß,

    Simon2.


Anmelden zum Antworten