Tomaz Fernandes
Tomaz Fernandes

Reputation: 2584

Creating a bidimensional array of pointers to objects and passing them to other classes

I´m new to C++ and have researched about arrays, pointers and so on, but I can´t figure out how to make this work. Hope you can help!

I need an two dimensional array frases that contains 3 x 2 objects MGFrase. They will be retrieved by a method getFrase so I can use MGFrase´s method setTone to change it´s property altura, which is an array of ints.

In the code below, I expected to change alturas[0] of frases[1, 0] but it keeps changing frases[0, 0].

Is this the right way to create the array? Is there a problem in the methods?

If my question is not clear enough or isn´t on par with the forum´s rules please let me know so I can edit it, I´m new here.

Thank you all in advance!

MGComposition::MGComposition(){
    MGFrases** frases;
    frases = new MGFrase* [3];
    for( int n = 0 ; n < 3 ; n ++ ){
        frases [n] = new MGFrase[2];
    }

    for( int n = 0 ; n < 3 ; n ++ ){
        frases[n, 0] = new MGFrase();
        frases[n, 1] = new MGFrase();
    }
}

MGFrase* MGComposition::getFrase( int channel , int numFrase ){
    return frases[ channel, numFrase] ;
}

void MGComposition::log(){
    cout << "- Composition --\n";
    for( int n = 0 ; n < 3 ; n ++ ){
         frases[ n , 0]->log();
         frases[ n , 1]->log();
    }
}


MGFrase::MGFrase(){
   int alturas [10];
}

void MGFrase::setTone(int tone, int index) {
    alturas[index] = tone;
}

void MGFrase::log() {

    cout << "\n\nLog de MGFrase\n";

    cout << "\nAlturas \n";

    for (int nota = 0; nota < numNotes; nota++) {
        cout << alturas [nota] << ", ";
    }
}

MGGenerator::MGGenerator() {

  MGComposition* composition;
  composition = theComposition;

  MGFrase* fraseDoBaixo;
  fraseDoBaixo = composition->getFrase(1, 0);
  fraseDoBaixo->setTone(8, 0);
  composition->log();

}

PS: This is how it is now with the solution:

MGFrase*** frases;
frases = new MGFrase** [3];
for( int n = 0 ; n < 3 ; n ++ ){
    frases [n] = new MGFrase*[2];
}

for( int n = 0 ; n < 3 ; n ++ ){
    frases[n][0] = new MGFrase();
    frases[n][1] = new MGFrase();
}

Upvotes: 2

Views: 73

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

An array of pointers with two dimensions implemented as a jagged array needs three asterisks: one asterisk per dimension, plus an asterisk for it being an array of pointers. A pair of square brackets could work to replace one asterisk. Your declaration new MGFrase* [3] makes an array of three pointers, hence it is missing one asterisk.

This whole asterisk counting business quickly gets rather annoying. Fortunately, you can avoid all of it by using C++ containers, such as std::array<T,N> or std::vector<T> in place of arrays of pointers. Here is how you could make it work:

std::array<std::array<std::unique_ptr<MGFrase>,2>,3> frases;

MGComposition::MGComposition(){
    for( int n = 0 ; n < 3 ; n ++ ){
        frases[n][0] = make_unique<MGFrase>(new MGFrase());
        frases[n][1] = make_unique<MGFrase>(new MGFrase());
    }
}

This approach uses a fixed-size 2×3 array of std::unique_ptr<MGFrase> objects, which takes care of memory cleanup for you. Now your code would not create a memory leak due to a missing destructor.

Upvotes: 1

NathanOliver
NathanOliver

Reputation: 180415

You are not properly indexing your arrays. Each dimension needs to have its own square brackets []. So for a two dimensional array you would access it as:

foo[row][col]

What you have:

frases[n, 0] = new MGFrase();

Is using the comma operator which ignores the left hand side and uses the right hand side for the index.

With that you can fix you function as:

MGComposition::MGComposition(){

    frases = new MGFrase* [3];
    for( int n = 0 ; n < 3 ; n ++ ){
        frases [n] = new MGFrase[2];
    }

    for( int n = 0 ; n < 3 ; n ++ ){
        frases[n][0] = new MGFrase();
        frases[n][1] = new MGFrase();
    }
}

MGFrase* MGComposition::getFrase( int channel , int numFrase ){
    return frases[ channel][numFrase] ;
}

void MGComposition::log(){
    cout << "- Composition --\n";
    for( int n = 0 ; n < 3 ; n ++ ){
         frases[n][0]->log();
         frases[n][1]->log();
    }
}

MGFrase::MGFrase(){
   int alturas [10];

}

void MGFrase::setTone(int tone, int index) {
    alturas[index] = tone;
}


MGGenerator::MGGenerator( MGComposition* theComposition ) {

  MGComposition* composition;
  composition = theComposition;

  MGFrase* fraseDoBaixo;
  fraseDoBaixo = composition->getFrase(1, 0);
  fraseDoBaixo->setTone(8, 0);

}

Upvotes: 1

Related Questions