So I'm storing a 2D dynamic Array into a matrix struct:
struct Matrix {
int ncol;
int nrow;
double **mat;
};
typedef struct Matrix Matrix;
I then have a function that takes the contents from a 2D array and stores it into the matrix:
// Initializes matrix mat whose values are the passed in 2D array
// Made Matrix **mat a double pointer so that I can initialize the Matrix *pointer from Main
void matrix_initializeFromArray(Matrix **mat, int nrow, int ncol, double array[][ncol]) {
(*mat) = (Matrix*) malloc(sizeof(Matrix*));
(*mat)->mat = (double**) malloc(nrow*sizeof(double*));
for(int i = 0; i < nrow; i++) {
(*mat)->mat[i] = (double*) malloc(ncol*sizeof(double*));
for(int j = 0; j < ncol; j++) { // intialize all values to array values
(*mat)->mat[i][j] = array[i][j];
}
}
(*mat)->ncol = ncol;
(*mat)->nrow = nrow;
}
Where this is the destructor for the matrix:
// Destructor
void matrix_destructor(Matrix **mat) {
for(int i = 0; i < (*mat)->nrow; i++) {
free((*mat)->mat[i]);
}
free((*mat)->mat);
free(*mat);
}
A small example of this is the following:
void main() {
Matrix *temp;
double array[1][1];
array[0][0] = 34;
matrix_initializeFromArray(&temp, 1, 1, array);
matrix_print(temp);
matrix_destructor(&temp);
}
This code executes normally on gdb and valgrind in my Linux Ubuntu but for some reason it creates this error while I run it on Windows.
warning: HEAP[a.exe]:
warning: Heap block at 00B51710 modified at 00B5171C past requested size of 4
I ran through the gdb on Windows and it occurs at this line in the destructor on the first loop: free((*mat)->mat[i]);
Any Help?
I have simplified your code, matrix_print is missing
The issue was with the malloc
when you allocate something you get a pointer to the memory, for example
malloc(sizeof(double)); returns a pointer to a memory area that can store a double so a double *
malloc(sizeof(double*)); returns a pointer to a memory are that can store a pointer to a double, so a double **`
#include <stdio.h>
#include <stdlib.h>
struct Matrix {
int ncol;
int nrow;
double **mat;
};
typedef struct Matrix Matrix;
void matrix_initializeFromArray(Matrix *mat, int nrow, int ncol, double array[][ncol]) {
mat->ncol = ncol;
mat->nrow = nrow;
mat->mat = malloc(nrow * sizeof(double*));
for(int i = 0; i < nrow; i++) {
mat->mat[i] = malloc(ncol*sizeof(double));
for(int j = 0; j < ncol; j++) { // intialize all values to array values
mat->mat[i][j] = array[i][j];
}
}
}
void matrix_wipe(Matrix *mat) {
for(int i = 0; i < mat->nrow; i++) {
free(mat->mat[i]);
}
free(mat->mat);
}
int main(void) {
Matrix temp;
double array[1][1];
array[0][0] = 34;
matrix_initializeFromArray(&temp, 1, 1, array);
matrix_wipe(&temp);
return 0;
}
I'm doing a project for school and I have a problem and I can't figure out how to solve it. I'm trying to allocate memory for a triple pointer in a function that I will be able to use it as a 2D array, save data and then use it in a different function. But for some reason I can't use the data once I'm out of the function.
BTW I have to use the variables that is writing in the function (float m1[ROWS][COLS], float m2[ROWS][COLS], float ***C).
int mat_mul(float m1[ROWS][COLS], float m2[ROWS][COLS], float ***C)
{
int i, j, k;
C = (float ***)malloc(sizeof(float*) * 3);
for (i = 0; i < 3; i++) {
C[i] = (float **)malloc(sizeof(float*) * 3);
for (j = 0; j < 3; j++) {
C[i][j] = (float *)malloc(sizeof(float) *3);
}
}
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
(*C)[i][j] = 0;
for (k = 0; k < ROWS; k++) {
(*C)[i][j] += m1[i][k] * m2[k][j];
}
}
}
printf_s("%.1f\n", (*C)[0][0]);
}
int i,j;
float Results[ROWS][COLS];
float Angle1[6], Angle2[6];
Angle_Reader("data_q.csv", &Angle1, &Angle2);
Angle_Converter(&Angle1, &Angle2);
for (i = 0; i < 1; i++) {
float Matrix1[ROWS][COLS] = { {cos(Angle1[i]),-sin(Angle1[i]),L1*cos(Angle1[i])},{sin(Angle1[i]),cos(Angle1[i]),L1*sin(Angle1[i])},{0,0,1} };
float Matrix2[ROWS][COLS] = { {cos(Angle2[i]),-sin(Angle2[i]),L2*cos(Angle2[i])},{sin(Angle2[i]),cos(Angle2[i]),L2*sin(Angle2[i])},{0,0,1} };
mat_mul(&Matrix1, &Matrix2, &Results);
}
printf_s("\n");
printf_s("%.1f\n", Results[0][0]);
This:
for (i = 0; i < 1; i++) {
float Matrix1[ROWS][COLS] = { {cos(Angle1[i]),-sin(Angle1[i]),L1*cos(Angle1[i])},{sin(Angle1[i]),cos(Angle1[i]),L1*sin(Angle1[i])},{0,0,1} };
float Matrix2[ROWS][COLS] = { {cos(Angle2[i]),-sin(Angle2[i]),L2*cos(Angle2[i])},{sin(Angle2[i]),cos(Angle2[i]),L2*sin(Angle2[i])},{0,0,1} };
mat_mul(&Matrix1, &Matrix2, &Results);
}
Should not be in a loop as is.
Either move the declaration above the loop, then in the loop, use index values ( i.e. Matrix2[i][j] ) instead of ROWS, COLS,
float Matrix1[ROWS][COLS] = {0};
float Matrix2[ROWS][COLS] = {0};
//Note: these initializers work only for 3x3 array
//Forcing ROWS == 3 and COLS == 3
float data1[ROWS][COLS] = { {cos(Angle1[0]),-sin(Angle1[1]),L1*cos(Angle1[2])},{sin(Angle1[0]),cos(Angle1[1]),L1*sin(Angle1[2])},{0,0,1} };
float data2[ROWS][COLS] = { {cos(Angle2[0]),-sin(Angle2[1]),L2*cos(Angle2[2])},{sin(Angle2[0]),cos(Angle2[1]),L2*sin(Angle2[2])},{0,0,1} };
...
if(Results)
{
for (i = 0; i < 1; i++)
{
Matrix1[i][j] = data1[i][j];
Matrix2[i][j] = data2[i][j];
...
mat_mul(&Matrix1, &Matrix2, &Results);
}
...or remove the for loop altogether and modify the i and j indexes from Angle1[i] to hard-coded values eg: Angle1[0], Angle1[1],... so that the initializers will populate the 2D arrays.
float Matrix1[ROWS][COLS] = { {cos(Angle1[0]),-sin(Angle1[1]),L1*cos(Angle1[2])},{sin(Angle1[0]),cos(Angle1[1]),L1*sin(Angle1[2])},{0,0,1} };
float Matrix2[ROWS][COLS] = { {cos(Angle2[0]),-sin(Angle2[1]),L2*cos(Angle2[2])},{sin(Angle2[0]),cos(Angle2[1]),L2*sin(Angle2[2])},{0,0,1} };
mat_mul(&Matrix1, &Matrix2, &Results);
Regarding creating memory, Nothing in your code indicates the need for a 3D array. As stated in comments, the reason for float ***C in the mat_mul(., ., float ***C) function prototype is to accommodate passing the address of a 2D matrix ( eg. &Results ), when calling function so that it can be modified. Even then, it would be an improvement to move the logic necessary to create the memory for that variable into its own function, and allocate the memory before it is passed as a variable:
float **Results = Create2D(COLS, ROWS);
if(Results)
{
for (i = 0; i < 1; i++)
{
...
...
mat_mul(&Matrix1, &Matrix2, &Results);
}
//When finished using, free Results
free2D(Results, COLS)
The functions Create2D() and its companion could be implemented as:
float ** Create2D(int c, int r)
{
float **arr;
int y;
arr = calloc(c, sizeof(float *));
for(y=0;y<c;y++)
{
arr[y] = calloc(r, sizeof(float));
}
return arr;
}
void free2D(float **arr, int c)
{
int i;
for(i=0;i<c;i++)
{
free(arr[i]);
}
free(arr);
}
So I've got a 2D Array which I am creating like this:
int** init_grid(int cell_grid_size) {
// matrix variables
int *memory_grid;
int **matrix;
int i;
int j;
// memory for matrix
memory_grid = malloc(cell_grid_size * cell_grid_size * sizeof(int));
matrix = malloc(cell_grid_size * sizeof(int *));
// fill matrix with rows
for(i = 0; i < cell_grid_size; i++) {
matrix[i] = &memory_grid[i*cell_grid_size];
}
// return fresh matrix
return matrix;
}
As you can see it's initialising a matrix of integers. However, I'd like to to initialize a matrix of integer arrays of size 2 (ie a 3D Matrix) but I can't quite seem to get my head around how to add the next dimension.
Any help would be greatly appreciated.
void grid_init(int* matrix, unsigned int xsize, unsigned int ysize, unsigned int unsigned int zsize)
{
unsigned int matrix_size;
// flatten matrix size in Byte
matrix_size = xsize*ysize*zsize*sizeof(int);
matrix = (int*)malloc(matrix_size);
memset(matrix, 0, sizeof(matrix_size);
}
Once matrix is built, you can loop through it using that loop:
void grid_fill(int* matrix, int value, unsigned int xsize, unsigned int ysize, unsigned int zsize)
{
int i,j,k;
for(k=0; k<zsize; k++)
{
for(i=0; i<ysize; i++)
{
for(j=0; j<xsize; j++)
{
matrix[j+i*xsize+k*ysize*xsize] = value;
}
}
}
}
For an int *** pointing to an array of pointers of type int **. Each pointing to an int *. Each int * pointer to an array of int.
Allocation checks for NULL omitted for brevity.
int*** init_grid(size_t xsize, size_t ysize, size_t zsize) {
int ***matrix = malloc(sizeof matrix[0] * xsize);
for (x = 0; x < xsize; x++) {
matrix[x] = malloc(sizeof matrix[x][0] * ysize);
for (y = 0; y < ysize; y++) {
matrix[x][y] = malloc(sizeof matrix[x][y][0] * zsize);
// or to zero-out the `int` data
matrix[x][y] = calloc(zsize, sizeof matrix[x][y][0]);
}
}
return matrix;
}
Use size_t for array indexing and sizing.
To free:
void free_grid(int ***matrix, size_t xsize, size_t ysize) {
if (matrix) {
for (x = 0; x < xsize; x++) {
if (matrix[x]) {
for (y = 0; y < ysize; y++) {
free(matrix[x][y])
}
}
free(matrix[x]);
}
free(matrix);
}
}
I was experimenting some basic C code that defines an int matrix with pointers.
typedef int **Matrix;
Matrix createMatrix(int lines, int columns) {
int i, j;
Matrix m = (Matrix) malloc(sizeof(int) * lines * columns);
for (i = 0; i < lines; ++i) {
for (j = 0; j < columns; ++j) {
m[i][j] = 0;
}
}
return m;
}
int main(int argc, char**argv) {
Matrix m = createMatrix(5, 10);
// ...
if (m[2][3] == 20) {
// ...
}
return 0;
}
However, these m[i][j] accesses are throwing segmentation faults. What's wrong here? Too many asterisks?
I was convinced that a pointer to a pointer to an int was effectively the same as a matrix.
Your allocation of the Matrix data item assumes you're accessing it linearly with a single index. If you want to access it with two indices, e.g., m[1][1] you need to allocate each dimension:
Matrix m = malloc(sizeof(int *) * lines);
for ( int i = 0; i < lines; i++ )
m[i] = malloc(sizeof(int) * columns);
Note also that you should not type cast malloc.
I've wrote the following code to implement matrix multiplication but repeatedly i got segmentation fault error. It's seems to everything be OK. can anybody tell my what's the problem.
this is the code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int matrixSize;
double ** a, ** b, ** c;
typedef struct tparms {
int row;
int col;
}tparms_t;
double ** allocateMatrix() {
int i;
double *vals, **temp;
//allocate values
vals = (double *) malloc (matrixSize * matrixSize * sizeof(double));
// allocate vector of pointers
temp = (double **) malloc (matrixSize * sizeof(double*));
for(i=0; i < matrixSize; i++)
temp[i] = &(vals[i * matrixSize]);
return temp;
}
void* multiply (void* _arg){
tparms_t * arg = (tparms_t *) _arg;
int i;
double sum;
for (i=0; i<matrixSize; i++)
sum += a[arg->row][i] * b[i][arg->col];
c[arg->row][arg->col] = sum;
}
void main(int argc, char *argv[]) {
pthread_t *threads;
if (argc != 2) {
printf("Usage: %s <size>, where size is dimension of square matrix\n", argv[0]);
exit(1);
}
int matrixSize = atoi(argv[1]);
threads = (pthread_t *) malloc(matrixSize * matrixSize * sizeof(pthread_t));
a = allocateMatrix();
b = allocateMatrix();
c = allocateMatrix();
int i, j;
for (i=0; i<matrixSize; i++){
for (j=0; j<matrixSize; j++){
a[i][j] = i + j;
b[i][j] = i + j;
}
}
for (i=0; i<matrixSize; i++){
for (j=0; j<matrixSize; j++){
tparms_t * tt = (tparms_t *)malloc(sizeof(tparms_t));
tt->row = i;
tt->col = j;
pthread_create(&threads[i*matrixSize + j], NULL, multiply, (void*)tt);
}
}
// two for for arrays
for (i=0; i<matrixSize; i++){
for (j=0; j<matrixSize; j++){
//do something ...
pthread_join(threads[i*matrixSize+j], NULL);
}
}
// end of two fors
}
there is a struct to pass data to threads, allocation function to allocate arrays and in main function i decide to create a thread for each of matrix elements. then a join function to wait until all threads do their job and create the c matrix elements.
You have int matrixSize = atoi (argv[1] );. Remove int because that creates another local instance of matrixSize.