Thread: Problem of allocation memory

  1. #1
    Registered User
    Join Date
    Mar 2020
    Posts
    18

    Problem of allocation memory

    hey guys i have a little project i need to write a program that can calculate two matrix and put the sum in triple pointer,for first i need to allocate memory for triple pointer .
    my problem is that when i try to free i got error
    i will show you the relevant parts of the code/
    the Error is :

    __fastfail(FAST_FAIL_STACK_COOKIE_CHECK_FAILURE);
    Code:
    int mat_mul(float m1[ROWS][COLS], float m2[ROWS][COLS], float *** C){
        int i, j;
        float temp[6], temp1[6];
        float res[ROWS][COLS];
    
    
        allocate_mem(C);
        read_file("data_q.csv", temp, temp1);
        for (i = 0; i < 6; i++) {
            GetValue(&m1[ROWS][COLS], &m2[ROWS][COLS], temp, temp1, i);
            multiply(&m1[ROWS][COLS], &m2[ROWS][COLS], C);
            if (C!=NULL)
            return 1;
            else
                return -1;
        }
    }
    Code:
    void multiply(float mat1[][COLS], float mat2[][COLS], float res[][COLS])    {
            int i, j, k;
            for (i = 0; i  <= COLS; i++)
            {
                for (j = 0; j <= COLS; j++)
                {
                    res[i][j] = 0;
                    for (k = 0; k <= COLS; k++)
                        res[i][j] += mat1[i][k] * mat2[k][j];
                }
            }
            
        }
    Code:
    void deallocate_mem(float*** arr) {
        for ( int i = 0; i < COLS; i++)
            free((*arr)[i]);
        free(*arr);
    }
    Code:
    void allocate_mem(float*** arr){
        *arr = (float**)malloc(COLS * sizeof(float*));
        for (int i = 0; i < COLS; i++)
            (*arr)[i] = (float*)malloc(ROWS * sizeof(float));
    Code:
    void GetValue(float m1[ROWS][COLS], float m2[ROWS][COLS],float* q1,float* q2,int i) {
    
            m1[0][0] = m1[1][1] = cos(q1[i]);
            m2[0][0] = m2[1][1] = cos(q2[i]);
            m1[0][2] = m1[1][2] = m2[0][2] = m2[1][2] = 0;
            m1[0][1] = sin(q1[i]);
            m2[0][1] = sin(q2[i]);
            m1[1][0] = -sin(q1[i]);
            m2[1][0] = -sin(q2[i]);
            m1[2][2] = 1;
            m2[2][2] = 1;
            m1[2][0] = 0.5*cos(q1[i]);
            m2[2][0] = 0.5*cos(q2[i]);
            m1[2][1] = 0.5*sin(q1[i]);
            m2[2][1] = 0.5*sin(q2[i]);
    
    
    }
    Last edited by cbeginner12334; 05-30-2020 at 02:01 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,091
    You seem to have a fundamental problem: you're dealing with matrices of ROWS number of rows and COLS number of columns. You cannot multiply two such matrices unless they are square matrices.

    If you are really dealing only with square matrices such that ROWS and COLs are always going to be the same value, then stop messing around with with different constants as if you're allowing for matrices that are not square matrices. Just have a single constant, maybe call it DIM. If not, I suggest a redesign. Declare a struct like this:
    Code:
    typedef struct {
        float **entries;
        int rows;
        int cols;
    } Matrix;
    Now, your memory allocation and deallocation functions will look like this (you'll need to add error checking):
    Code:
    void allocate_mem(Matrix *matrix) {
        float *data = malloc(matrix->rows * matrix->cols * sizeof(matrix->entries[0][0]));
        matrix->entries = malloc(matrix->rows * sizeof(matrix->entries[0]));
        for (int i = 0; i < matrix->rows; i++) {
            matrix->entries[i] = data + i * matrix->cols;
        }
    }
    
    void deallocate_mem(Matrix *matrix) {
        free(matrix->entries[0]);
        free(matrix->entries);
        matrix->entries = NULL;
    }
    Then for multiplication:
    Code:
    int mat_mul(const Matrix *m1, const Matrix *m2, Matrix *result)
    at the start, you'll do a sanity check to see if m1 really can be multiplied by m2 based on m1->cols == m2->rows, and you'll set result->rows and result->cols accordingly before passing it to allocate_mem. Notice that the storage for the Matrix object itself (not the entries) is done even before you call mat_mul, allowing the caller the flexibility of having say, a Matrix object on the stack whose address gets passed to mat_mul, or perhaps a dynamically allocated one represented by a pointer.

    On the other hand, you are only dealing with square matrices, then delete allocate_mem and deallocate_mem. They are a waste of time and effort. You already know that your result matrix is going to be a float[COLS][COLS] (or float[DIM][DIM], if you take my suggestion). No dynamic allocation needed.
    Last edited by laserlight; 05-30-2020 at 04:07 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Mar 2020
    Posts
    18
    Quote Originally Posted by laserlight View Post
    You seem to have a fundamental problem: you're dealing with matrices of ROWS number of rows and COLS number of columns. You cannot multiply two such matrices unless they are square matrices.

    If you are really dealing only with square matrices such that ROWS and COLs are always going to be the same value, then stop messing around with with different constants as if you're allowing for matrices that are not square matrices. Just have a single constant, maybe call it DIM. If not, I suggest a redesign. Declare a struct like this:
    Code:
    typedef struct {
        float **entries;
        int rows;
        int cols;
    } Matrix;
    Now, your memory allocation and deallocation functions will look like this (you'll need to add error checking):
    Code:
    void allocate_mem(Matrix *matrix) {
        float *data = malloc(matrix->rows * matrix->cols * sizeof(matrix->entries[0][0]));
        matrix->entries = malloc(matrix->rows * sizeof(matrix->entries[0]));
        for (int i = 0; i < matrix->rows; i++) {
            matrix->entries[i] = data + i * matrix->cols;
        }
    }
    
    void deallocate_mem(Matrix *matrix) {
        free(matrix->entries[0]);
        free(matrix->entries);
        matrix->entries = NULL;
    }
    Then for multiplication:
    Code:
    int mat_mul(const Matrix *m1, const Matrix *m2, Matrix *result)
    at the start, you'll do a sanity check to see if m1 really can be multiplied by m2 based on m1->cols == m2->rows, and you'll set result->rows and result->cols accordingly before passing it to allocate_mem. Notice that the storage for the Matrix object itself (not the entries) is done even before you call mat_mul, allowing the caller the flexibility of having say, a Matrix object on the stack whose address gets passed to mat_mul, or perhaps a dynamically allocated one represented by a pointer.

    On the other hand, you are only dealing with square matrices, then delete allocate_mem and deallocate_mem. They are a waste of time and effort. You already know that your result matrix is going to be a float[COLS][COLS] (or float[DIM][DIM], if you take my suggestion). No dynamic allocation needed.

    wow ,first of all thank you !!!
    but in my project with must use the triple pointer

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,302
    > GetValue(&m1[ROWS][COLS], &m2[ROWS][COLS], temp, temp1, i);
    This isn't how you pass on your input parameters.

    Code:
    GetValue(m1, m2, temp, temp1, i);
    > multiply(&m1[ROWS][COLS], &m2[ROWS][COLS], C);
    ...
    > void multiply(float mat1[][COLS], float mat2[][COLS], float res[][COLS])
    Your C is of type float ***, and that in no way is the same as float res[][COLS]

    This might work.
    Code:
    multiply(m1, m2, *C);  // turns your ***C into a ** to match what multiply expects
    Along with
    Code:
    void multiply(float mat1[][COLS], float mat2[][COLS], float **res)    {
            int i, j, k;
            for (i = 0; i  <= COLS; i++)
            {
                for (j = 0; j <= COLS; j++)
                {
                    res[i][j] = 0;
                    for (k = 0; k <= COLS; k++)
                        res[i][j] += mat1[i][k] * mat2[k][j];
                }
            }
             
        }
    All those <= COLS mean you're running off the ends of your arrays.

    The idiomatic loop for subscripting arrays of dimension N is for ( i = 0 ; i < N ; i++ )
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,091
    Quote Originally Posted by cbeginner12334
    but in my project with must use the triple pointer
    So, this is a school project with artificial constraints? Then indeed you have to use a triple pointer, but you should also be aware that this might be because your instructor is a three star programmer (might be individually skilled, but is a pretty poor programmer when it comes to programming in teams or for the long haul because of an inability or refusal to use abstractions appropriately).

    Yet, you haven't addressed the point I raised: are you dealing only with square matrices?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    Mar 2020
    Posts
    18
    Quote Originally Posted by laserlight View Post
    So, this is a school project with artificial constraints? Then indeed you have to use a triple pointer, but you should also be aware that this might be because your instructor is a three star programmer (might be individually skilled, but is a pretty poor programmer when it comes to programming in teams or for the long haul because of an inability or refusal to use abstractions appropriately).

    Yet, you haven't addressed the point I raised: are you dealing only with square matrices?
    yes its a academic project
    and COLS==ROWS==2
    yes all matrix square/

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,091
    Quote Originally Posted by cbeginner12334
    yes its a academic project
    and COLS==ROWS==2
    yes all matrix square/
    I'm still really puzzled as to why your instructor wants to use dynamic memory allocation instead of yet another 2D array, but let's chalk that up to you learning dynamic memory allocation for a possibly jagged 2D array.

    As I mentioned, it would be best to replace ROWS and COLS with a single constant like DIM.

    Salem mentioned a few points to take note in post #4. I'd say that the key here is to understand that you're trying to allocate memory for a float**, but you need a float*** only the memory allocation function because you're using the parameter as an out parameter. Recall that if you have an int in main and you want to change it from within a function such that it affects the int in the main function, you need to pass a pointer. For example:
    Code:
    #include <stdio.h>
    
    void foo1(int *x)
    {
        *x = 123;
    }
    
    void foo2(int x)
    {
        x = 456;
    }
    
    int main(void)
    {
        int x = 0;
        foo1(&x);
        printf("x=%d\n", x); // x has been changed to 123
        foo2(x);
        printf("x=%d\n", x); // x was not changed to 456
        return 0;
    }
    So, if you have a float** and want to change it (i.e., assign to it the address of the dyanamically allocated memory) in your memory allocation function, you need a float***. In all other places, as long as you are only dealing with the content of the matrix, you only need a float** parameter. This is true even of the memory deallocation function (unless you want to set the pointer to be a null pointer from within the memory deallocation function).

    This should allow you to keep things simple while continuing to use the float*** as required where it is in fact needed.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem with memory allocation
    By Elias Zaguri in forum C Programming
    Replies: 2
    Last Post: 05-23-2016, 07:59 AM
  2. Memory allocation problem
    By rtlm in forum C Programming
    Replies: 6
    Last Post: 09-01-2011, 02:45 AM
  3. memory allocation problem
    By ccoder01 in forum C Programming
    Replies: 12
    Last Post: 04-24-2004, 08:22 PM
  4. Memory allocation problem
    By Thantos in forum C Programming
    Replies: 6
    Last Post: 01-23-2004, 12:56 AM
  5. memory allocation problem....help..
    By CyC|OpS in forum C Programming
    Replies: 8
    Last Post: 10-18-2002, 09:26 AM

Tags for this Thread