Reputation: 2584
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 int
s.
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
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
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