0

Hope everyone is doing well.

I am trying to write a simple Matrix Library in C by creating a Matrix struct, and then using its memory address to execute operations.

Here is my header file for the library:

/*
To compile:

g++ -c simpMat.cpp
ar rvs simpMat.a simpMat.o
g++ test_simpMat.c simpMat.a
*/

#ifndef SIMPMATH_H
#define SIMPMAT_H

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

typedef struct{
    uint8_t nRows;
    uint8_t nCols;
    uint8_t nElements;
    float **elements;
}simpMat;

/**
*@brief simpMat_Init
*@param simpMat
*@param uint8_t
*@param uint8_t
*@param uint8_t
*@param float* 
*@retval NONE
*/
void simpMat_Init(simpMat *Matrix, uint8_t nRows, uint8_t nColumns, uint8_t nElements, float elements[]);

/**
*@brief simpMat_Print
*@param simpMat
*@retval NONE
*/
void simpMat_Print(simpMat *Matrix);

/**
*@brief simpMat_Delete
*@param simpMat
*@retval NONE
*/
void simpMat_Delete(simpMat *Matrix);

#endif

Here is the source file:

#include "simpMat.h"

void simpMat_Init(simpMat *Matrix, uint8_t nRows, uint8_t nColumns, uint8_t nElements, float elements[])
{
    Matrix->nRows = nRows;
    Matrix->nCols = nColumns;
    Matrix->nElements = nElements;

    Matrix->elements = (float**)malloc(nRows * sizeof(float*));
    for (uint8_t i = 0; i < nRows; i++)
    {
        Matrix->elements[i] = (float*)malloc(nColumns * sizeof(float));
    }
    
    uint8_t count = 0;

    for (uint8_t i = 0; i < nRows; i++)
    {
        for (uint8_t j = 0; j < nColumns; j++)
        {
            Matrix->elements[i][j] = elements[count];
            count++;
        }
    }      
        
}

void simpMat_Print(simpMat *Matrix)
{
    for (uint8_t i = 0; i < Matrix->nRows; i++)
    {
        for (uint8_t j = 0; j < Matrix->nCols; j++)
        {
            printf("%d ", Matrix->elements[i][j]);

        }

        printf("\n");
    }
}


void simpMat_Delete(simpMat *Matrix)
{
    uint8_t n = Matrix->nRows;
    while(n) free(Matrix->elements[--n]);
    free(Matrix->elements);
}

I also wrote a small test program to see if I can successfully assign elements to the matrix; such as:

#include "simpMat.h"
#include "stdio.h"

int main()
{
    simpMat Matrix1;

    float toAppend[9] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};

    simpMat_Init(&Matrix1, 3, 2, 9, toAppend);

    printf("MATRIX ELEMENTS ARE:\n");

    simpMat_Print(&Matrix1);

    simpMat_Delete(&Matrix1);

    return 0;

}

I compiled my library and the main program with the following commands on CMD:

g++ -c simpMat.cpp
ar rvs simpMat.a simpMat.o
g++ test_simpMat.c simpMat.a

However, when I run the executable, I get the following output:

MATRIX ELEMENTS ARE:
0 0
0 0
0 0

I could not understand the reason I cannot assign values. I am fairly new to the Dynamic Memory Allocation subject and I suspect that I had a misconception about the methodology. Can you help me with that?

1 Answer 1

1

If you use a debugger and step through your program looking at the memory, you should see the data is actually there. Your question assumes the problem is assignment, whereas it's actually in your output. This kind of thing is most easily discoverable with a debugger.

The actual problem is your matrix elements are float. But you are using %d specifier in your printf, which is for int values. Change this to %f.

Separately, you should reconsider the purpose of the nElements parameter. You are not doing any sanity tests before copying the array (for example, ensuring rows * cols does not exceed that value). It doesn't appear to have any relation to the actual matrix and should not be stored.

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

2 Comments

I am cursing myself now. Thank you so much! You are right about the nElements parameter. I was planning to use it to check the dimensions of the source array but have not implemented it yet.
@kucar You could probably check the dimensions with rows/columns, so nElements isn't needed and may make the code more fragile because you're doing an array of pointers to rows. And, given that, a bit of a moot point, but uint8_t may be too small. If you do end up needing it, I'd use uint32_t for the case where the number of elements is >= 256. Might also use uint32_t for rows/cols as well.

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.