I have custom struct for 2D Matrices. I'm using this struct inside a function to initialize a 2D matrix where every element value is set to 0. I've also have another function to print a matrix to terminal (for debugging purposes).
When I write the struct and the functions inside the main.c
, they work. The problem is when I put them in a separate file and call them from that file I get a runtime error: Exception thrown: write access violation
.
In my program I have 3 file: main.c
, my_lib.h
, my_lib.c
. The struct is stored inside my_lib.h
and the function is in my_lib.c
. Inside main.h
I'm using Windows 10 & coding in Visual Studio 2017 v15.9.10
The program compiles but gives a runtime error Exception thrown: write access violation
Well, it seems it was my own fault that this was happening.
Actually, I was trying to run this code on my work computer. I've written the the original code on my personal computer where the main.c
, my_lib.h
& my_lib.c
version was working. Then I copied the folder that I was working on and tried to continue on my work computer. Both my computer runs on Windows 10 OS and both have the same version of VS 2017.
On my personal computer the solution explorer was like:
But on my work computer, the solution opened as:
Everything, including the folder hierarchy are same on both computers. It seems, copying a project folder is not a good idea.
When I, created a new C project on my work computer and added the my_lib.c
and my_lib.h
manually, everything worked.
But I'm still curious why I was getting an Exception error... And how can I correct this problem of copying without creating a new project in VS?
main.c
#include <stdio.h>
typedef struct Matrix {
int rows; // number of rows
int cols; // number of columns
double** data; // a pointer to an array of n_rows pointers to rows
}Matrix;
Matrix* make_matrix(int n_rows, int n_cols);
void print_matrix(Matrix* m);
int main() {
Matrix* m1 = make_matrix(2, 5);
print_matrix(m1);
return 0;
}
// CREATE A MATRIX WITH N_ROWS AND N_COLUMNS AND INITIALIZE EACH VALUE AS 0
Matrix* make_matrix(int n_rows, int n_cols) {
Matrix* matrix = malloc(sizeof(Matrix));
matrix->rows = n_rows;
matrix->cols = n_cols;
double** data = malloc(sizeof(double*) * n_rows);
for (int x = 0; x < n_rows; x++) {
data[x] = calloc(n_cols, sizeof(double));
}
matrix->data = data;
return matrix;
}
// PRINT GIVEN MATRIX TO COMMAND LINE
void print_matrix(Matrix* m) {
for (int x = 0; x < m->rows; x++) {
for (int y = 0; y < m->cols; y++) {
printf("%f", m->data[x][y]);
printf("|");
}
printf("\n");
}
}
main.c
#include "my_lib.h"
int main(){
// Create a 2 by 5 matrix & then print it to terminal
Matrix* m1 = make_matrix(2, 5);
print_matrix(m1);
return 0;
}
my_lib.h
#pragma once
// Our custom 2D matrix struct
typedef struct Matrix {
int rows; // number of rows
int cols; // number of columns
double** data; // a pointer to an array of n_rows pointers to rows
}Matrix;
Matrix* make_matrix(int n_rows, int n_cols);
void print_matrix(Matrix* m);
my_lib.c
#include "my_lib.h"
#include <stdio.h>
// CREATE A MATRIX WITH N_ROWS AND N_COLUMNS AND INITIALIZE EACH VALUE AS 0
Matrix* make_matrix(int n_rows, int n_cols) {
Matrix* matrix = malloc(sizeof(Matrix));
matrix->rows = n_rows;
matrix->cols = n_cols;
double** data = malloc(sizeof(double*) * n_rows);
for (int x = 0; x < n_rows; x++) {
data[x] = calloc(n_cols, sizeof(double));
}
matrix->data = data;
return matrix;
}
// PRINT GIVEN MATRIX TO COMMAND LINE
void print_matrix(Matrix* m) {
for (int x = 0; x < m->rows; x++) {
for (int y = 0; y < m->cols; y++) {
printf("%f", m->data[x][y]);
printf("|");
}
printf("\n");
}
}
The reason you get the crash is not related at all to the fact that you have one or two .c files in your project but it's because you forgot to include <stdlib.h>
in my_lib.c
.
This triggers following warnings:
my_lib.c(8) : warning C4013: 'malloc' undefined; assuming extern returning int
my_lib.c(13): warning C4013: 'calloc' undefined; assuming extern returning int
my_lib.c(13): warning C4047: '=': 'double *' differs in levels of indirection from 'int'
my_lib.c(8): warning C4047: 'initializing': 'Matrix *' differs in levels of indirection from 'int'
my_lib.c(11): warning C4047: 'initializing': 'double **' differs in levels of indirection from 'int'
You get away with it on a 32 bit build because the size of int
is the same as the size of a pointer.
On the other hand if you build your program as 64 bit program, the warnings become really relevant, because now pointers are 64 bits wide, but as the compiler assumes that malloc
etc. return int
s (32 bit values), everything get messed up.
Actually these warnings should be considered as errors.
Here you decide if you want a 32 or a 64 bit build:
Add #include <stdlib.h>
here in my_lib.c
:
#include "my_lib.h"
#include <stdlib.h> // <<<<<<<<<<<<<
#include <stdio.h>
// CREATE A MATRIX WITH N_ROWS AND N_COLUMNS AND INITIALIZE EACH VALUE AS 0
Matrix* make_matrix(int n_rows, int n_cols) {
Matrix* matrix = malloc(sizeof(Matrix));
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With