Learning C ++. Now I pass OOP, in the task I need to work with dynamic memory. The problem is when I increment a variable like this:
this->a[this->index++] == &aa; , this->index becomes equal to numbers like 6422016, 6422048 etc. When I do this: this->index++; this->a[this->index - 1] = &aa; this->index++; this->a[this->index - 1] = &aa; With a variable, everything is fine.
What is it connected with?

Compiler: MINGW 3.3
OS: win10
CMake: 3.6.2
GDB: 7.8

Job Code:

 #include <iostream> #include <string> using namespace std; class Date { int year; public: Date(int y): year(y) {} ~Date() { cout << "Date destructor" << endl; } void setDate(int y) { this->year = y; } int getYear() { return this->year; } }; class A{ Date date; public: A(Date& d): date(d) {} void setDate(Date& d) { this->date = d; } Date* getDate(); }; Date* A::getDate() { Date* new_date = &this->date; return new_date; } class B { A *a[]; int index = 0; public: ~B() { delete[] a; } void addA(A& aa) { this->a[this->index++] = &aa; } // НС Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ void func(int); void func2(int); }; void B::func(int year) { int counter = 0; for(int i = 0; i < this->index; i++) { cout << i << endl; if(this->a[i]->getDate()->getYear() == year) { cout << "Yes " << year << endl; counter = i; } } func2(counter); } void B::func2(int a) { cout << this->a[a]->getDate()->getYear() << endl; } int main() { Date d(2000); A a(d), c(d); B b; b.addA(a); b.addA(c); b.func(2000); return 0; } 

Thank!

    3 answers 3

    A WARNING

    The code below can cause gag reflexes and a terrible desire to minus without reading. Abstain!


    every time you want to make an array through new[] , you should think, can you still use std::vector ?


    The code below should be used only to satisfy the teacher, to get a credit if everything else does not work.

    Construction type A *a[]; can compile, but only gcc. This piece is called Flexible array member . And although it is not according to the standard, but gcc can close its eyes.

    So, let's make it work :)

    The first thing to do is to move the array declaration to the end of the class. That is, instead of

     class B { A *a[]; int index = 0; public: 

    need to write like that

     class B { int index = 0; A *a[]; public: 

    and it is better to take the private section completely to the end.

    Also, delete memory in destructor. In our case, remove the call to delete here (you can delete this destructor altogether).

     ~B() { delete[] a; } 

    Now you need to do more so that under the class B to allocate enough memory. Let's use the placement new thing. Now the main will be

     int main() { Date d(2000); A a(d), c(d); // Π²Ρ‹Π΄Π΅Π»ΠΈΠΌ Π±ΡƒΡ„Π΅Ρ€, Ρ€Π°Π·ΠΌΠ΅Ρ€ взят Π·Π°Π²Π΅Π΄ΠΎΠΌΠΎ большой char *buf = new char[64*1024]; // Π° это Ρ‚Π°ΠΊΠΎΠΉ конструктор:) B *b = new (buf) B (); b->addA(a); b->addA(c); b->func(2000); // Π²Ρ‹Π·Ρ‹Π²Π°Π΅ΠΌ явно дСструктор b->~B(); // ΠΈ почистим Π·Π° собой ΠΏΠ°ΠΌΡΡ‚ΡŒ delete[] buf; return 0; } 

    Now the code is compiled and seems to work as expected. Moreover, there are even no leaks and memory executions (I checked valgrind).

    Once again, this thing is very gcc's. Already, even the clang refuses to compile it. Studio compiler does not tolerate this either. Is it worth using even in homework? not. Not worth it. Unless your course is called β€œnon-obvious and outdated gcc features”.

      1. The size of the array must be known at compile time. Therefore, this announcement

         A *a[]; 

        not correct

      2. You cannot use the delete [] operator on an array name.

      3. The array was not dynamically allocated.

         class B { A *a[]; int index = 0; public: ~B() { delete[] a; } //.. 
      • The teacher said that in this assignment to use such arrays is mandatory. - OptimalStrategy
      • @ justpainm8 Either you misunderstand him or he is wrong. - Vlad from Moscow
      • Thank you. So I need to do something like this? A* a[number]; ? - OptimalStrategy
      • @ justpainm8 Yes, only the number should be a constant expression. And you cannot delete this array with the help of delete [], and also you cannot delete its elements, since these pointers are not created by the class object. - Vlad from Moscow

      Probably, the teacher expects something more prosaic, for example (separate lines)

       A **a; // НуТСн массив ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ? Объявим ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ a = new A* [ΡΠΊΠΎΠ»ΡŒΠΊΠΎΠ½ΠΈΠ±ΡƒΠ΄ΡŒ]; // создаСм динамичСский массив ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ delete[] a; // ΡƒΠ½ΠΈΡ‡Ρ‚ΠΎΠΆΠ°Π΅ΠΌ динамичСский массив Π² дСструкторС 

      And if it is not known beforehand and it is necessary to stretch the array (or even compress), then you have to create a new one, all that needs to be rewritten into it, the old one is destroyed, etc. Book such a task.