Thread: Making a 2d array (matrix) in a struct

  1. #1
    Registered User
    Join Date
    Feb 2009
    Posts
    68

    Making a 2d array (matrix) in a struct

    If I'm trying to make a 2d array in a struct, do I have to make the struct a certain size when I write the prototype? I can't explain it very well, but here's what I'm talking about:

    Code:
    {
    	int Matrix[][];
    	int row;
    	int column;
    };
    This is what I have ^


    I want it to think I have 1 matrix that looks like:

    Code:
    {
    	int Matrix[30][25];
    	int row = 30;
    	int column = 25;
    }
    and I want another matrix that looks like:

    Code:
    {
    	int Matrix[25][10];
    	int row = 25;
    	int column = 10;
    }

    So I can multiply the matrices to get one that looks like

    Code:
    {
    	int Matrix[30][10];
    	int row = 30;
    	int column = 10;
    }
    Can I make the Matrices a certain size "on the go", or do I have to make them all 50x50, just in case I have on the size of 50x50?

    I fail at explaining, I hope you understood my question...Sorry if I gave you a headache :|

  2. #2
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    Code:
    struct matrix
    {
        int** values;
    };
    
    matrix mtrx;
    
    // allocate it as so...
    mtrx.values = new int*[width]; // allocates one dimension
    
    for(int i = 0; i < size; i++) {
        mtrx.values[i] = new int[height]; // allocates the second dimension
    }

  3. #3
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Methinks your first example will be a compiler error.

    Quote Originally Posted by madmax2006 View Post
    Can I make the Matrices a certain size "on the go", or do I have to make them all 50x50, just in case I have on the size of 50x50?
    You can't resize something declared this way:
    Code:
    int mat[20][30];
    However, you could use a pointer to a pointer:
    Code:
    int **mat;
    And later make it any size you want -- which you must, since as is it has no dimensions at all.
    Code:
    int i, rows, cols, **mat;
    mat = malloc(rows*sizeof(int*));
    for(i=0;i<rows;i++) mat[i] = malloc(cols*sizeof(int));
    Notice the first malloc is an array of pointers (int*) whereas the second one is for the actual array of (int). After that you can use mat[x][x] normally.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #4
    Registered User
    Join Date
    Feb 2009
    Posts
    68
    Quote Originally Posted by scwizzo View Post
    Code:
    mtrx.values = new int*[width]; // allocates one dimension
    
    for(int i = 0; i < size; i++) {
        mtrx.values[i] = new int[height]; // allocates the second dimension
    }
    What is "new" supposed to do?

    Btw, thanks for the help. I guess I had tunnel vision about the ways it could be done

  5. #5
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by madmax2006 View Post
    What is "new" supposed to do?
    It's C++, please excuse scwizzo.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #6
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    Quote Originally Posted by MK27 View Post
    It's C++, please excuse scwizzo.
    oops, i forget what part of the forum I'm in sometimes. Use malloc() instead of new. MK27 has the C way to do it, th way I listed is C++. Essentially 'new' is the C++ way to use malloc.

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by madmax20006
    I'm trying to understand this code, but some of it doesn't make sense to me.

    Code:

    mat = malloc(rows*sizeof(int*));

    How do you know that you're supposed to do sizeof(int*)?
    If I understand it correctly, you're just multiplying rows x the "sizeof" a column?
    **mat is a pointer (to a pointer), with no memory allocated.

    You need to set "rows" to a definate value, obviously, eg, 50. Then:
    mat = malloc(rows*sizeof(int*))
    This allocates enough space for 50 int pointers. The reason we need int pointers is because each first dimension element of mat will also be a pointer (to an actual array of ints) -- that's why mat is a "pointer to a pointer". This parallels the fact that it makes no sense to refer to a matrix value, mat[11] -- however, you can refer to the 11th row. And (to reiterate), in the code, mat[11] is literally a pointer to a 1 dimensional array of ints (ie, a row in your matrix).

    Next, each of those 50 row pointers needs space for an actual row. The length of the row is determined by the number of columns (say 30).
    for (i=0;i<rows;i++) mat[i] = malloc(cols*sizeof(int));
    That's why we use (int) here but (int*) previously.

    Seems a bit complicated just for a 2D matrix, doesn't it (this is why C is considered "low level" -- it must attend to a lot of fine details). Why can't you just go:

    mat = malloc(rows*cols*sizeof(int));

    You can. That's all the same you need for 1000 (rows*cols, if rows is 50 and cols 20) ints. The problem is, that will be a one dimensional array of 1000, like:

    int array[1000]

    which you could use both to store a matrix, but you will keep having to do some weird math in order to find your elements. That's awkward for the programmer and most likely less optimal for the compiler as well.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    Registered User
    Join Date
    Feb 2009
    Posts
    68
    Thanks for the lengthy explanation, it helps a lot.

    Say I make a declaration:

    int ***mat;

    What is the type of
    **mat
    *mat
    mat


    Are they all int's?

    I deleted my last post because I was going to ask it in a different way, but you explained it well enough.

  9. #9
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    All but the last one are pointers to ints (mat by itself is an int). Hence they will all be 4 bytes in size on a 32 bit machine, it's true even for a declaration like: char *mat; by the way.

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by madmax2006 View Post
    Say I make a declaration:
    int ***mat;
    Say you don't Seriously -- what would be the purpose of this?

    Not to say it never happens, but they are not considered good style, and WRT matrices, no matter how many dimensions to your matrix (mat[10][10][10][10]), none of them will contain a *** -- you will just get layers of **. I'll leave you to think about why.

    What is the type of
    **mat
    *mat
    mat


    Are they all int's?
    int **mat is a pointer to an int pointer.
    int *mat is an int pointer.
    int mat is just an int.

    None of them has to involve an array, eg:
    Code:
    int mat, *p = &mat, *p2 = &p;
    "Pointers to pointers" are also used to pass the address of a pointer to a function so that it can be reassigned:
    Code:
    void example_func(int **ptr);  /* prototype */
    int x, *ptr=&x;
    example(&ptr);  /* a call */
    Inside example_func, you can now ressign ptr to something other than x and the consequences will be global (x will remain unchanged). You'll run into a need for that sooner or later.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485

    Thumbs up

    Quote Originally Posted by MK27 View Post
    int **mat is a pointer to an int pointer.
    int *mat is an int pointer.
    int mat is just an int.
    Yeah, that is a more correct way of putting it.

  12. #12
    Registered User
    Join Date
    Feb 2009
    Posts
    68
    Quote Originally Posted by MK27 View Post
    Say you don't Seriously -- what would be the purpose of this?
    Just to get a better understanding of how these bastard pointers work

    One thing I hate about C, are the pointers. In fact, it may be the only thing I hate about C. I understood them last semester, and then I took a memory dump over the winter break.

    As far as I'm concerned, pointers are the least of my worries. If I understood them last semester, I'll be able to re-learn them in no time.

  13. #13
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    A pointer is just like any other variable. It holds a value. Everything in C holds a value. Everything. Some values are characters, some are numbers, some are addresses. If it's a pointer, it's holding an 'address of variable type N' as its value.


    Quzah.
    Hope is the first step on the road to disappointment.

  14. #14
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by madmax2006 View Post
    Just to get a better understanding of how these bastard pointers work

    One thing I hate about C, are the pointers. In fact, it may be the only thing I hate about C. I understood them last semester, and then I took a memory dump over the winter break.

    As far as I'm concerned, pointers are the least of my worries. If I understood them last semester, I'll be able to re-learn them in no time.
    Hmm. I started a page to explain pointer usage (kind of) a while ago, to save having to explain some things, and still haven't got around to finishing it, but you may want to have a look anyway:

    Pointers: Pass by Value, Pass by Reference

    I kind of focus on the fact that a pointer has three values associated with it:
    Code:
    int x, *ptr=x;   /* declaration */
    ptr;     /* the value stored in ptr -- the address of x */
    &ptr;    /* the address of ptr itself */
    *ptr;     /* the value stored in the variable at the address stored in ptr */
    whereas a normal variable (such as x) only has two.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  15. #15
    Registered User
    Join Date
    Feb 2009
    Posts
    68
    You guys have helped a lot, thanks for everything. I just have to add 1 more function (multiplying matrices) and I'm finished. I'll take a look at that page when I'm finished.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  2. towers of hanoi problem
    By aik_21 in forum C Programming
    Replies: 1
    Last Post: 10-02-2004, 01:34 PM
  3. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  4. Hi, could someone help me with arrays?
    By goodn in forum C Programming
    Replies: 20
    Last Post: 10-18-2001, 09:48 AM