multi-dimensional array

Discussion in 'C++' started by Tom, Oct 15, 2003.

  1. Tom

    Tom Guest

    Hi,

    I am new in programming (and certainly in C++). I want to creat a
    five-dimensional array. Two dimensions are numbers and other three are
    variable.
    One of the variables is an array whose dimension depends on one of the
    remaing two variables. Can anyone give me some suggestion what I am
    supposed to do?

    What I did was the following:

    .....
    typedef struct {
    int matrix[10][10];
    } Name1;

    ....

    main(){
    ...
    int dim1; // variable dimension;
    int* ar=new int[dim1];
    int dim2; // variable dimension;

    vector<vector<vector<Name1> > > aaa;

    for(int i1=0;i1<dim2;i1++){
    for(int i2=0;i2<dim1;i2++){
    for(int i3=0;i3<ar[dim1];i3++){
    for(int i4=0;i4<10;i4++){
    for(int i5=0;i5<10;i5++){
    aaa[i1][i2][i3].matrix[i4][i5]=a known 5d matrix
    element;
    }
    }
    }
    }
    }

    delete[] ar;

    }


    However, when I compiled it always gave me a message Segmentation
    fault (presumable this is an initialized issue, I am not sure as I
    wrote before I am new in programming). My program compiles fine if I
    remove the above segment.

    Thanks in advance,
    Tom
    Tom, Oct 15, 2003
    #1
    1. Advertising

  2. "Tom" <> wrote...
    > Hi,
    >
    > I am new in programming (and certainly in C++). I want to creat a
    > five-dimensional array. Two dimensions are numbers and other three are
    > variable.
    > One of the variables is an array whose dimension depends on one of the
    > remaing two variables. Can anyone give me some suggestion what I am
    > supposed to do?
    >
    > What I did was the following:
    >
    > ....
    > typedef struct {
    > int matrix[10][10];
    > } Name1;
    >
    > ...
    >
    > main(){


    Should be

    int main(){

    > ...
    > int dim1; // variable dimension;
    > int* ar=new int[dim1];


    What's that for? And how much are you allocating? What's the value
    of 'dim1' here?

    > int dim2; // variable dimension;
    >
    > vector<vector<vector<Name1> > > aaa;


    How does the 'aaa' know how many elements should be in its vectors?
    In order to fill it in, you have to allocate some first. Read about
    'resize' member of 'vector' template.

    >
    > for(int i1=0;i1<dim2;i1++){
    > for(int i2=0;i2<dim1;i2++){
    > for(int i3=0;i3<ar[dim1];i3++){
    > for(int i4=0;i4<10;i4++){
    > for(int i5=0;i5<10;i5++){
    > aaa[i1][i2][i3].matrix[i4][i5]=a known 5d matrix
    > element;
    > }
    > }
    > }
    > }
    > }
    >
    > delete[] ar;
    >
    > }
    >
    >
    > However, when I compiled it always gave me a message Segmentation
    > fault (presumable this is an initialized issue, I am not sure as I
    > wrote before I am new in programming). My program compiles fine if I
    > remove the above segment.


    Of course you get a segmentation error. The 'aaa' vector does not
    contain any elements, and you're trying to access them.

    Victor
    Victor Bazarov, Oct 15, 2003
    #2
    1. Advertising

  3. Tom

    Guest

    On 15 Oct 2003 11:54:32 -0700, Tom <> wrote:

    > Hi,
    >
    > I am new in programming (and certainly in C++). I want to creat a
    > five-dimensional array. Two dimensions are numbers and other three are
    > variable.
    > One of the variables is an array whose dimension depends on one of the
    > remaing two variables. Can anyone give me some suggestion what I am
    > supposed to do?
    >
    > What I did was the following:
    >
    > ....
    > typedef struct {
    > int matrix[10][10];
    > } Name1;


    And now :

    template <class T> class m3 {
    std::vector<T> data;
    int dimx,dimy,dimz;
    public:
    m3(int sizex,int sizey,int sizez,const T& t) : data(i*j*k,t),dimx(sizex)
    ,dimy(sizey),dimz(sizez) {}
    T& operator ()(int i,int j,int k) { return data[(i*dimy+j)*dimz+k]; }
    };
    m3<Name1> should do it for us.

    >
    > ...
    >
    > main(){
    > ...
    > int dim1; // variable dimension;
    > int* ar=new int[dim1];
    > int dim2; // variable dimension;


    don't exactly undersand what's going on with this dimension , do you need
    more of them ?

    > vector<vector<vector<Name1> > > aaa;


    it may work too but it's more complicated - indirect and 3 dimensions have
    resize capabilities - do you want them too ?
    Right now 3 first dimensions are 0, no data (and memory space) in your
    vector.

    > for(int i1=0;i1<dim2;i1++){
    > for(int i2=0;i2<dim1;i2++){
    > for(int i3=0;i3<ar[dim1];i3++){
    > for(int i4=0;i4<10;i4++){
    > for(int i5=0;i5<10;i5++){


    that would mean dimensions are dim2,dim1,ar[dim1]

    m3<Name1> data(dim2,dim1,ar[dim1],something);


    > aaa[i1][i2][i3].matrix[i4][i5]=a known 5d matrix
    > element;
    > }
    > }
    > }
    > }
    > }
    >
    > delete[] ar;
    >
    > }
    >
    >
    > However, when I compiled it always gave me a message Segmentation
    > fault (presumable this is an initialized issue, I am not sure as I
    > wrote before I am new in programming). My program compiles fine if I
    > remove the above segment.
    >
    > Thanks in advance,
    > Tom
    >




    --
    grzegorz
    , Oct 15, 2003
    #3
  4. > I am new in programming (and certainly in C++). I want to creat a
    > five-dimensional array. Two dimensions are numbers and other three are
    > variable.


    What about getting a good book? See www.accu.org

    > One of the variables is an array whose dimension depends on one of the
    > remaing two variables. Can anyone give me some suggestion what I am
    > supposed to do?


    I think your program is the most undefined-behaviorial one I ever seen.

    > What I did was the following:
    >
    > ....
    > typedef struct {
    > int matrix[10][10];
    > } Name1;


    C++ is not C :

    struct Name1
    {
    int matrix[10][10];
    };

    > ...
    >
    > main(){


    Undefined behavior 1 : main() returns an int. Always.

    int main()
    {

    > ...


    What's that?

    > int dim1; // variable dimension;


    Here, dim1 is not initialized, that is, it contains garbage. Accessing it
    results in undefined behavior.

    > int* ar=new int[dim1];


    Ugh. Undefined behavior 2 : you are using an uninitialized object (dim1) to
    allocate an object. The best thing you could get is a crash.

    > int dim2; // variable dimension;
    >
    > vector<vector<vector<Name1> > > aaa;


    Here, 'aaa' is empty. You *cannot* put values in it other than with
    push_back() or insert().

    > for(int i1=0;i1<dim2;i1++){
    > for(int i2=0;i2<dim1;i2++){
    > for(int i3=0;i3<ar[dim1];i3++){
    > for(int i4=0;i4<10;i4++){
    > for(int i5=0;i5<10;i5++){
    > aaa[i1][i2][i3].matrix[i4][i5]=a known 5d matrix
    > element;
    > }
    > }
    > }
    > }
    > }


    Undefined behavior 3 and 4 : you are using 'dim1' and 'dim2', both of which
    are not initialized. How long do you think that loop is going to last ?
    Undefined behavior 5 : you are accessing non existent elements of 'aaa'.

    > delete[] ar;
    >
    > }


    For what I can see, you want something like

    # include <vector>

    using std::vector;

    const int MATRIX_SIZE_X = 10;
    const int MATRIX_SIZE_Y = 10;


    struct Name1
    {
    int matrix[MATRIX_SIZE_X][MATRIX_SIZE_Y];
    };


    int main()
    {
    const int SIZE_1 = 10;
    const int SIZE_2 = 10;
    const int SIZE_3 = 10;

    vector< vector< vector< Name1 > > > aaa;

    for ( int i = 0; i < SIZE_1; ++i )
    {
    aaa.push_back(vector< vector< Name1> > () );

    for ( int j = 0; j < SIZE_2; ++j )
    {
    aaa.push_back(vector< Name1 > () );

    for ( int k = 0; k < SIZE_3; ++k )
    {
    Name1 name;

    for ( int l = 0; l < MATRIX_SIZE_X; ++l )
    {
    for ( int m = 0; m < MATRIX_SIZE_Y; ++m )
    {
    name.matrix[l][m] = something;
    }
    }

    aaa[j].push_back( name );
    }
    }
    }
    }

    (untested)


    Jonathan
    Jonathan Mcdougall, Oct 16, 2003
    #4
  5. Tom

    Tom Guest

    Hi all,

    Thanks for helping me. I guess I did not tell you exactly what I
    wanted.
    Jonathan's program is not what I wanted because Jonathan fixed all
    three dimentions. Below is my naive program.


    #include<iostream>
    #include<vector>
    #include<string>
    #include<fstream>
    #include<set>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<algorithm>

    #define FIX 20

    using namespace std;

    typedef struct { // I will change to C++ style as
    int matrix[10][10]; // Jonathan suggested
    } Name1;


    int score(char x,char y){
    if(((x=='A') && (y=='A')) || ((x=='B') && (y=='B')) ||
    ((x=='C') && (y=='C')) || ((x=='D') && (y=='D'))){
    return 1;
    }
    else{
    return 0;
    }
    }

    //there are more lines here but it has nothing to do with our
    discussion.
    // That's why I put ....
    int main(){ // Missing int was a typo.

    ifstream input_file1("file1");
    string line_file1,seq_prob;
    vector<string> line1;

    while(getline(input_file1, line_file1))
    line1.push_back(line_file1);

    vector<string> line1_string;
    vector<string> title1_string;
    int c0=0; int d0=0;

    for(int j=0;j<line1.size();j++){
    if(line1[j][0]=='>'){
    title1_string.push_back(line1[j]);
    c0++;
    }
    else{
    line1_string.push_back(line1[j]);
    d0++;
    }
    }

    int dim1 = line1_string.size(); // or one can use int dim1 = c0;

    ifstream input_file2("file2");
    string line_file2;
    vector<string> line2;
    vector<string> line2_title;

    while(getline(input_file2, line_file2))
    line2.push_back(line_mir_target);

    vector<string>* tartemp = new vector<string>[line2.size()];

    int c1=0; int d1=0;

    for(int j=0;j<line2.size();j++){
    if(line2[j][0]=='>'){
    line2_title.push_back(line2[j]);
    c1++;
    }
    else{
    tartemp[c1-1].push_back(line2[j]);
    }
    }

    string pp="";

    for(int ttt=0;ttt<tartemp[0].size();ttt++){
    pp+=tartemp[0][ttt];
    }

    int dim2 = c1;

    string* line2_string =new string[dim2];

    for(int cc1=0; cc1<dim2;cc1++){
    for(int fff=0; fff<tartemp[cc1].size();fff++){
    line2_string[cc1] += tartemp[cc1][fff];
    }
    }


    int* ar = new int[dim2];

    for(int f2=0;f2<dim2;f2++){
    ar[f2] = line2_string[f2].size() - FIX;
    }

    // No I want to make a five-dimensional array with dimension dim1,
    dim2, ar, 10 and 10

    vector<vector<vector<Name1> > > aaa;

    // I tried to initialize aaa.

    for(int p=0; p<dim1;p++){
    for(int t=0;t<dim2;t++){
    for(int s=0;s<ar[t];s++){
    for(int row=0; row<10;row++){
    for(int col=0;col<10;col++){
    aaa[p][t].matrix[row][col]=-1;
    }
    }
    }
    }
    }

    //known[][][][][]

    for(int p=0; p<dime1;p++){
    for(int t=0;t<dim2;t++){
    for(int s=0;s<ar[t];s++){
    for(int c=0;c<10;c++){
    for(int r=0;r<10;r++){
    aaa[p][t].matrix[r][c] =
    score((line2_string[t].substr(s,10))[c],(line1_string[p])[r]));
    }

    }
    }
    }
    }


    delete[] ar;
    delete[] tartemp;

    }



    Many thanks,
    Tom
    Tom, Oct 16, 2003
    #5
  6. "Tom" <> wrote...
    > [...]
    > // No I want to make a five-dimensional array with dimension dim1,
    > dim2, ar, 10 and 10
    >
    > vector<vector<vector<Name1> > > aaa;
    >
    > // I tried to initialize aaa.



    'aaa' is _empty_ here. That means it doesn't _have_ any elements
    for you to initialise. You need to _resize_ it so it has something:

    aaa.resize(dim1);

    >
    > for(int p=0; p<dim1;p++){


    Although 'aaa' now has 'dim1' elements, each 'aaa' is _empty_.
    You need to resize them (every loop cycle would be OK) to give
    it something to _initialise_:

    aaa[p].resize(dim2);

    > for(int t=0;t<dim2;t++){


    The same here:

    aaa[p][t].resize(ar[t]);

    > for(int s=0;s<ar[t];s++){
    > for(int row=0; row<10;row++){
    > for(int col=0;col<10;col++){
    > aaa[p][t].matrix[row][col]=-1;
    > }
    > }
    > }
    > }
    > }
    >
    > //known[][][][][]
    >
    > for(int p=0; p<dime1;p++){


    'dime1'? Typos again?

    > for(int t=0;t<dim2;t++){
    > for(int s=0;s<ar[t];s++){
    > for(int c=0;c<10;c++){
    > for(int r=0;r<10;r++){
    > aaa[p][t].matrix[r][c] =
    > score((line2_string[t].substr(s,10))[c],(line1_string[p])[r]));
    > }
    >
    > }
    > }
    > }
    > }
    >
    >
    > delete[] ar;
    > delete[] tartemp;
    >
    > }


    HTH

    Victor
    Victor Bazarov, Oct 16, 2003
    #6
  7. Tom

    Tom Guest

    Thanks Victor,

    Your suggestion works fine. However, my program with your suggestion
    run pretty slow. When I have an input file around 3MB, then it did not
    run (Aborted). Do you have any suggestion about optimizing? What
    should I do to optimize it?

    Thanks again,
    Tom

    > > for(int p=0; p<dime1;p++){

    >
    > 'dime1'? Typos again?


    Yes. It's a typo.
    Tom, Oct 16, 2003
    #7
  8. "Tom" <> wrote...
    > Thanks Victor,
    >
    > Your suggestion works fine. However, my program with your suggestion
    > run pretty slow. When I have an input file around 3MB, then it did not
    > run (Aborted). Do you have any suggestion about optimizing? What
    > should I do to optimize it?


    You should find the place in your program that holds everything up
    (use a special program called "profiler"), then analyse that place
    and see what you can do to speed it up.

    WRT optimisations there are very few real generic recommendations.
    They are, mostly, rules or laws. For example, the 80/20 rule: 80
    percent of the time in your program is spent in 20 percent of the
    code (so there is no sense trying to speed up the rest of the code,
    it's not going to make any real difference). Or the "don't try
    optimising before you know what to optimise" rule (that's where
    a profiler should be of great help).

    Good luck!

    Victor
    Victor Bazarov, Oct 17, 2003
    #8
  9. Tom

    Tom Guest

    Hi Victor,

    Thanks a lot. I want to load a file around 5MB into a buffer and do
    some manipulation. My program could not run. It said Aborted. Would
    you have any idea what wrong with my program below? I really
    appreciate your comments.

    Thanks,
    Tom

    #include<iostream>

    #define tarlen 20

    int main(){

    ifstream input_target(TARGET_FILE);
    string line_mir_target;
    vector<string> target;
    vector<string> input_ft;

    while(getline(input_target, line_mir_target))
    target.push_back(line_mir_target);

    vector<string>* tartemp = new vector<string>[target.size()];

    int c1=0; int d1=0;

    for(int j=0;j<target.size();j++){
    if(target[j][0]=='>'){
    input_ft.push_back(target[j]);
    c1++;
    }
    else{
    tartemp[c1-1].push_back(target[j]);
    }
    }
    int number_of_targets = c1;

    string* input_ts =new string[number_of_targets];

    for(int cc1=0; cc1<number_of_targets;cc1++){
    for(int fff=0; fff<tartemp[cc1].size();fff++){
    input_ts[cc1] += tartemp[cc1][fff];
    }
    //cout << input_ts[cc1] << endl;
    }

    int* n_targets = new int[number_of_targets];

    for(int f2=0;f2<number_of_targets;f2++){
    n_targets[f2] = input_target_seq[f2].size() - tarlen +1;
    }



    vector<vector<string> > ts;

    ts.resize(number_of_targets);

    for(int f33=0; f33<number_of_targets;f33++){
    ts[f33].resize(n_targets[f33]);
    }

    for(int f4=0;f4<number_of_targets;f4++){
    for(int kkk=0;kkk<n_targets[f4];kkk++){
    ts[f4][kkk]= input_ts[f4].substr(kkk,tarlen);
    cout << ts[f4][kkk] << endl;
    }
    }

    }
    Tom, Oct 18, 2003
    #9
  10. "Tom" <> wrote...
    > Hi Victor,
    >
    > Thanks a lot. I want to load a file around 5MB into a buffer and do
    > some manipulation. My program could not run. It said Aborted. Would
    > you have any idea what wrong with my program below? I really
    > appreciate your comments.
    >
    > Thanks,
    > Tom
    >
    > #include<iostream>
    >
    > #define tarlen 20
    >
    > int main(){
    >
    > ifstream input_target(TARGET_FILE);


    'TARGET_FILE' is undefined here. 'ifstream' is undefined as well,
    you might want to '#include <fstream>'.

    > string line_mir_target;


    'string' is undefined here. You forgot to '#include <string>'.

    > vector<string> target;


    'vector' is undefined. It can be cured by '#include <vector>'

    (and all those includes should probably be followed by the 'using'
    declaration)

    > vector<string> input_ft;
    >
    > while(getline(input_target, line_mir_target))
    > target.push_back(line_mir_target);
    >
    > vector<string>* tartemp = new vector<string>[target.size()];
    >
    > int c1=0; int d1=0;
    >
    > for(int j=0;j<target.size();j++){
    > if(target[j][0]=='>'){
    > input_ft.push_back(target[j]);
    > c1++;
    > }
    > else{
    > tartemp[c1-1].push_back(target[j]);
    > }
    > }
    > int number_of_targets = c1;
    >
    > string* input_ts =new string[number_of_targets];
    >
    > for(int cc1=0; cc1<number_of_targets;cc1++){
    > for(int fff=0; fff<tartemp[cc1].size();fff++){
    > input_ts[cc1] += tartemp[cc1][fff];
    > }
    > //cout << input_ts[cc1] << endl;
    > }
    >
    > int* n_targets = new int[number_of_targets];
    >
    > for(int f2=0;f2<number_of_targets;f2++){
    > n_targets[f2] = input_target_seq[f2].size() - tarlen +1;
    > }
    >
    >
    >
    > vector<vector<string> > ts;
    >
    > ts.resize(number_of_targets);
    >
    > for(int f33=0; f33<number_of_targets;f33++){
    > ts[f33].resize(n_targets[f33]);
    > }
    >
    > for(int f4=0;f4<number_of_targets;f4++){
    > for(int kkk=0;kkk<n_targets[f4];kkk++){
    > ts[f4][kkk]= input_ts[f4].substr(kkk,tarlen);
    > cout << ts[f4][kkk] << endl;
    > }
    > }
    >
    > }


    In this particular fragment:

    int c1=0;
    int d1=0;

    for(int j=0;j<target.size();j++)
    {
    if(target[j][0]=='>')
    {
    input_ft.push_back(target[j]);
    c1++;
    }
    else
    {
    tartemp[c1-1].push_back(target[j]);
    }
    }

    What if the very first 'target' element does NOT have the '>'
    character in the beginning? 'c1' is 0. 'tartemp[c1-1]' is
    'tartemp[-1]'. That's "before the beginnig of the vector".
    I doubt this should work.

    I cannot give you any more advice without knowing what the file
    is that you attempt to load. No, this is not an invitation to
    post it here or send it to me. Please learn to debug your own
    programs.

    Victor
    Victor Bazarov, Oct 19, 2003
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. kk_oop
    Replies:
    1
    Views:
    2,164
  2. Replies:
    7
    Views:
    842
    Ryan Stewart
    Feb 20, 2005
  3. John Harrison
    Replies:
    2
    Views:
    713
    John Harrison
    Jul 14, 2003
  4. Venkat
    Replies:
    4
    Views:
    972
    Venkat
    Dec 5, 2003
  5. Wirianto Djunaidi
    Replies:
    2
    Views:
    200
    Wirianto Djunaidi
    Apr 29, 2008
Loading...

Share This Page