2

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();
}
1
  • frases[ n , 0]; C++ is not Delphi or Pascal. A multidimension array in C++ requires separate [ ] for each dimension. Commented Jun 16, 2015 at 15:13

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

frases[n, 0] is not correct for a 2 dimensional array index.
The brackets were the first problem, but you nailed it with the 3 asterisks! This is actually an Arduino program, and I was told I not to use the std library. Going to make the destructor so it won´t leak memory. Thank you very much!
1

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);

}

2 Comments

If I do so I get "No viable overload ´=´ " and Xcode asks me to use frases[n][0] = *new MGFrase();, with the asterisk. But by doing this I would´t be creating objects, but pointers, isn´t it?
@Lajotas How is frases declared? Please edit you post to include that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.