Membery-Array Größe einer Klasse im Konstruktor setzen

(Firma: Neutron Mikroelektronik GmbH) #5169333
Lesenswert?

Hallo alle zusammen,

ich habe in einem avr Mikrocontroller c++ Projekt eine Klasse mit einem 
Array als Member. Jetzt möchte ich die Größe des Arrays im Konstruktor 
festlegen. Also für jede Instanz anders.

Nachdem ich jetzt erfahren habe, dass weder der c++ Ansatz mit new [] 
bzw. free noch die Verwendung von malloc bei avr funktioniert, habe ich 
keine Ahnung, wie ich so was umsetzen soll. Hier etwas Code als Beispiel 
zur Verdeutlichung.
1
typedef struct
2
{
3
    int a;
4
    int b;
5
} element_t;
6

7
class ElementsQueue 
8
{
9
    element_t items[42];
10
};

Ich möchte jetzt beim Instanziieren die 42 festlegen. Also per 
Konstruktor. Und ich stehe völlig auf dem Schlauch, wie man sowas 
umsetzt. Kann mir da jemand einen Tipp geben?
#5169344
Lesenswert?

Wolfgang K. schrieb:
> dass weder der c++ Ansatz mit new []
> bzw. free noch die Verwendung von malloc bei avr funktioniert

Das funktioniert sogar sehr gut. Du musst dann halt nur noch 
sicherstellen, dass du das Array nicht über seine Grenzen hinaus 
indizierst.
1
class ElementsQueue 
2
{
3
    element_t *items;
4

5
    ElementsQueue(unsigned n)
6
    {
7
        items = new element_t[n];
8
    }
9
};

Wenn du jetzt aber darauf hinaus willst, dass man zur Laufzeit damit 
rechnen muss, dass einem der RAM ausgeht, dann lässt sich dieses Problem 
nicht beheben. Da müsstest du dann zu Beginn den ganzen notwendigen 
Speicher allozieren und deine Objekte anlegen.
#5169356
Lesenswert?

möglicherweise ein potentieller Kandidat für ein Klassen-Template:
1
template <size_t size> struct element_queue
2
{
3
    struct element & operator [](int index) { return items[index]; };
4

5
    struct element items[size];
6
};
7

8
...
9

10
    struct element_queue<10> elements;
11

12
    elements[7].a = 4711;
13
...
#5174196
Lesenswert?

Felix U. schrieb:
> Ja free funktioniert auch. Du kannst natürlich die new[] und delete[]
> Wrapper auch einfach weglassen und direkt mit malloc/free arbeiten.
> Richtig Sinn macht die Unterscheidung ja sowieso erst mit Exceptions.

Nein. Das wesentliche ist, dass malloc nur den Speicher reserviert, 
während new[] auch die ggf. nötige Initialisierung (z.B. 
Konstruktor-Aufrufe) macht.
#5175215
Lesenswert?

Ich würde den Beitrag von Felix U. noch ergänzen:
1
class ElementsQueue
2
{
3
    element_t *items;
4

5
    ElementsQueue(unsigned n)
6
    {
7
        items = new element_t[n];
8
    }
9

10
    ~ElementsQueue()
11
    {
12
        // wichtig, damit der Speicher auch wieder freigegeben wird
13
        delete[] items;
14
    }
15
};
#5175258
Lesenswert?

Rolf M. schrieb:
> M.K. B. schrieb:
>>     ~ElementsQueue()
>>     {
>>         // wichtig, damit der Speicher auch wieder freigegeben wird
>>         delete[] items;
>>     }
>> };
>
> Dann aber auch um Copy-Konstruktor und Zuweisungsoperator kümmern! Also
> entweder =delete oder korrekt implementieren.

In modernem Cpp kein expl. new/delete mehr. In diesem Fall wäre der 
std::unique_ptr das richtige. Dann hat man auch das richtige 
default-Verhalten bzgl. copy/move.
Gast #5175290
Lesenswert?

Wilhelm M. schrieb:
> In diesem Fall wäre der
> std::unique_ptr das richtige. Dann hat man auch das richtige
> default-Verhalten bzgl. copy/move.

Wäre nicht ein std::vector<element_t> die bessere Wahl? Dann bekommt man 
alle (copy/move, constructor/operator=/destructor) speziellen 
Member-Funktionen gratis. Man muss sich die Anzahl der Elemente nicht 
selbst merken und falls benötigt, ist das Ändern der Anzahl einfach 
möglich. Außerdem kann man mit std::unique_ptr<element_t[]> kein 
ranged-for benutzen. Und ...
#5175295
Lesenswert?

mh schrieb:
> Wilhelm M. schrieb:
>> In diesem Fall wäre der
>> std::unique_ptr das richtige. Dann hat man auch das richtige
>> default-Verhalten bzgl. copy/move.
>
> Wäre nicht ein std::vector<element_t> die bessere Wahl? Dann bekommt man
> alle (copy/move, constructor/operator=/destructor) speziellen
> Member-Funktionen gratis. Man muss sich die Anzahl der Elemente nicht
> selbst merken und falls benötigt, ist das Ändern der Anzahl einfach
> möglich. Außerdem kann man mit std::unique_ptr<element_t[]> kein
> ranged-for benutzen. Und ...

Das kommt ganz darauf an ... Wenn es tatsächlich ne Queue werden soll, 
würde man den Container wohl eher generisch halten, sprich er schreibt 
sich ein Adapter-Template ...

... und verlagert das Probelm in den std::vector, den er sich für den 
avr-g++ auch selbst schreiben muss ...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren