"Write Acces Violation" After Using malloc() Inside a Function - c

Problem
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.hand the function is in my_lib.c. Inside main.h
I'm using Windows 10 & coding in Visual Studio 2017 v15.9.10
Output
The program compiles but gives a runtime error Exception thrown: write access violation
Edit:
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.cand 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?
Code
Just main.c ( Works)
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 & function in seperate files (Throws an exception)
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 ints (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));
...

Related

Cannot Assign Elements to Dynamically Allocated Two Dimensional Array in C

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?
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.

2-dimensional array in a struct in C

I'm trying to initialize a 2-dimensional array in a structure but I always get an error :
gcc -g -Wall -W -I/usr/include/SDL -c -o fractal.o fractal.c
In file included from fractal.c:2:0:
fractal.h:12:12: error: array type has incomplete element type ‘double[]’
double values[][];
Here's the code:
struct fractal {
char name[64];
int height;
int width;
double a;
double b;
double meanValue;
double values[][]; /*This line is causing the error*/
};
Ideally I'd like to initialize the height and width of the 2-dimensional array like this:
struct fractal {
/*... Same code as above ...*/
double values[width][height];
};
But then I get two other errors when compiling:
gcc -g -Wall -W -I/usr/include/SDL -c -o fractal.o fractal.c
In file included from fractal.c:2:0:
fractal.h:12:19: error: ‘width’ undeclared here (not in a function)
double values[width][height];
^
fractal.h:12:26: error: ‘height’ undeclared here (not in a function)
double values[width][height];
^
I've looked about everywhere but my code should work and I can't figure out why it doesn't.
Thanks for the help
As a disclaimer, this is something of an advanced topic, so if you are a beginner you might want to just back away from it entirely and just use a double* array followed by a call to malloc for each pointer. (Fine for beginners, unacceptable in professional code.)
It is an advanced topic since this particular case is a weakness in C. The feature you are trying to use, with an empty array at the end of a struct, is known as flexible array member. This only works for one dimension however. If both dimensions are unknown at compile time, you have to come up with a work-around.
The allocation part is as for any flexible array member: allocate the struct dynamically and make size for the trailing array.
fractal_t* f = malloc(sizeof *f + sizeof(double[height][width]) );
(In this case taking advantage of the convenient VLA syntax, although a flexible array member is not a VLA.)
Technically, the last member of the struct is supposedly double[] now, or so says the struct declaration. But memory returned by malloc has no actual effective type until you access it, after which the effective type of that memory becomes the type used for the access.
We can use this rule to access that memory as if it was a double[][], even though the pointer type in the struct is a different one. Given a fractal f, the code for accessing through a pointer becomes something like this:
double (*array_2D)[width] = (double(*)[width]) f->values;
Where array_2D is an array pointer. The most correct type to use here would have been an array pointer to an array of double, double (*)[height][width], but that one comes with mandatory ugly accessing (*array_2D)[i][j]. To avoid such ugliness, a common trick is to leave out the left-most dimension in the array pointer declaration, then we can access it as array_2D[i][j] which looks far prettier.
Example code:
#include <stdlib.h>
#include <stdio.h>
typedef struct
{
char name[64];
size_t height;
size_t width;
double a;
double b;
double meanValue;
double values[];
} fractal_t;
fractal_t* fractal_create (size_t height, size_t width)
{
// using calloc since it conveniently fills everything with zeroes
fractal_t* f = calloc(1, sizeof *f + sizeof(double[height][width]) );
f->height = height;
f->width = width;
// ...
return f;
}
void fractal_destroy (fractal_t* f)
{
free(f);
}
void fractal_fill (fractal_t* f)
{
double (*array_2D)[f->width] = (double(*)[f->width]) f->values;
for(size_t height=0; height < f->height; height++)
{
for(size_t width=0; width < f->width; width++)
{
array_2D[height][width] = (double)width; // whatever value that makes sense
}
}
}
void fractal_print (const fractal_t* f)
{
double (*array_2D)[f->width] = (double(*)[f->width]) f->values;
for(size_t height=0; height < f->height; height++)
{
for(size_t width=0; width < f->width; width++)
{
printf("%.5f ", array_2D[height][width]);
}
printf("\n");
}
}
int main (void)
{
int h = 3;
int w = 4;
fractal_t* fractal = fractal_create(h, w);
fractal_fill(fractal); // fill with some garbage value
fractal_print(fractal);
fractal_destroy(fractal);
}
Dynamic dimensions arrays is not the point where C is at its best... Simple Variable Length Arrays were only introduced in the language in the C99 version and were made optional in C11 version. They are still not accepted in MSVC 2017...
But here, you are trying to set one in a struct. That is not supported at all because a struct must have a constant size(*) (how could be handled arrays of structs). So I am sorry but this code should not work and I know no way to express that in C language.
A common way would be to replace the 2D dynamic array with a pointer, allocate the pointer to a 2D array and then use it, but even this is not really simple.
You have to design your struct differently...
(*) The last element of a struct may be of an incomplete type, for example int tab[];. That is a dangerous feature because the programmer is responsable for providing room for it. But anyway you cannot build an array of incomplete types.
I encountered this problem while designing a struct to hold both the domain values (N x 1 vector) and the solution values (N x M matrix) in my ODE solver, so as to simplify the function interfaces. N and M are simulation-dependent and hence are unknown a priori. I solved it by using GNU Scientific Library's vector-matrix module. I found it more streamlined to work with than casting a FAM (albeit allocated as 2D) to a standalone whole-array-pointer.
After allocating memory for the struct, all we need to do is invoke gsl_matrix_alloc() to reserve space for the matrix. After we are done, calling gsl_matrix_free() will destroy it. Please note that these functions are data-type dependent as explained in the documentation.
Filename: struct_mat.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_statistics.h>
typedef struct _fractal {
char name[64];
size_t height;
size_t width;
double a;
double b;
double meanValue;
gsl_matrix *values;
} fractal;
fractal * fractal_create(size_t height, size_t width) {
fractal * fractalObj = (fractal *) malloc(sizeof(fractal));
fractalObj -> values = gsl_matrix_alloc(height, width);
if (fractalObj == NULL || fractalObj -> values == NULL) {
fprintf(stderr, "NULL pointer returned while allocating fractal object.. Exiting program.\n");
exit(EXIT_FAILURE);
}
fractalObj -> height = height;
fractalObj -> width = width;
fractalObj -> meanValue = 0.0;
return fractalObj;
}
void fractal_populate(fractal * fractalObj) {
srand(time(NULL));
double current_value = 0.0;
for (size_t r = 0; r < fractalObj -> height; ++r) {
for (size_t c = 0; c < fractalObj -> width; ++c) {
current_value = (double) rand() / (double) RAND_MAX;
gsl_matrix_set(fractalObj -> values, r, c, current_value);
}
}
}
void fractal_calcMeanValue(fractal * fractalObj) {
gsl_vector_view colVec;
for (size_t col = 0; col < fractalObj -> values -> size2; ++col) {
colVec = gsl_matrix_column(fractalObj -> values, col);
fractalObj -> meanValue += gsl_stats_mean(colVec.vector.data, colVec.vector.stride, colVec.vector.size);
}
fractalObj -> meanValue /= fractalObj -> values -> size2;
printf("\nThe mean value of the entire matrix is %lf\n", fractalObj -> meanValue);
}
void fractal_display(fractal * fractalObj) {
printf("\n");
for (size_t r = 0; r < fractalObj -> height; ++r) {
for (size_t c = 0; c < fractalObj -> width; ++c) {
printf("%lf ", gsl_matrix_get(fractalObj -> values, r, c));
}
printf("\n");
}
}
void fractal_delete(fractal * fractalObj) {
gsl_matrix_free(fractalObj -> values);
free(fractalObj);
}
int main(int argc, char const *argv[]){
// Program takes number of rows and columns as command line parameters
switch(argc) {
case 3:
printf("Running program..\n"); // to avoid the declaration-succeeding-label error
size_t height = atoi(argv[1]);
size_t width = atoi(argv[2]);
fractal * myFractal = fractal_create(height, width);
fractal_populate(myFractal);
fractal_display(myFractal);
fractal_calcMeanValue(myFractal);
fractal_delete(myFractal);
return 0;
default:
fprintf(stderr, "USAGE: struct_mat <rows> <columns>\n");
return 1;
}
}
Compile by linking with the GSL and GSL CBLAS libraries:
gcc -std=c99 struct_mat.c -o struct_mat -lgsl -lgslcblas -lm
You may install GSL via your distribution's package manager, Cygwin on Windows or by compiling the source.
In my limited experience, using a standard data structure proves to be far easier than wrestling with either FAMs or array-of-pointers-to-1D-arrays. However, the caveat is that we have to remember allocating memory for the matrix after allocating the struct itself.

dynamic allocation of 2d array function

So I have a program in C structured in 3 files: main.c, alloc.h and alloc.c. In the main.c function, I have the declaration of a pointer to another pointer to which I intend to alloc an n * m array:
#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
int main() {
int **mat, n, m;
alloc_matrix(&mat, int &n, int &m);
return 0;
}
In alloc.c I have the following declarations:
#ifndef ALLOC_H_INCLUDED
#define ALLOC_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
void alloc_matrix(int***, int*, int*);
#endif
In alloc.c I have the function:
void alloc_matrix(int ***mat, int *n, int *m) {
printf("\nn = "); scanf("%d", n);
printf("\nm = "); scanf("%d", m);
*mat = (int**)calloc(*n, sizeof(int*));
int i;
for (i = 0; i < *n; i++)
*(mat + i) = (int*)calloc(*m, sizeof(int));
}
But the program doesn't work. It enters some kind of loop and doesn't end.
If I allocate it in main it would work but I have no idea what I am doing wrong in the alloc function.
Here is the correct code. Your error was that in the definition of alloc_matrix, you used *(mat+i) in the allocation loop, which should be *(*mat+i) as, mat is a int*** so the base address for the 2D array would be in *mat. Then you need to move by offset i and then de-reference that memory location for the 1D array.
Main:
#include <stdio.h>
#include <stdlib.h>
#include "alloc.h"
int main()
{
int **mat,n,m;
alloc_matrix(&mat,&n,&m);
return 0;
}
alloc.h
#ifndef ALLOC_H_INCLUDED
#define ALLOC_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
void alloc_matrix(int***,int*,int*);
#endif
alloc.c :
void alloc_matrix(int ***mat,int *n,int *m)
{
printf("\nn = "); scanf("%d", n);
printf("\nm = "); scanf("%d", m);
*mat = (int**)calloc(*n,sizeof(int*));
int i;
for(i = 0; i < *n; i++)
*(*mat+i) = (int*)calloc(*m,sizeof(int));
}
The code for the read function :
void read_matrix(int ***mat,int n,int m)
{
int i,j;
for(i = 0; i < n; i++)
for(j = 0; j < m; j++)
{
printf("mat[%d][%d] = ", i, j);
scanf("%d", (*(*mat+i))+j);
}
}
The problem with it is that it only reads the first row and the it freezes.
void alloc_matrix(int ***mat,int *n,int *m)
There are two problems in this line. Neither is fatal but both are worth fixing.
First problem: A matrix in this program is represented as an int**. Why does alloc_matrix accept an int***? All standard functions that allocate something (malloc and friends) return a pointer to that something. This is an idiomatic way of doing things in C. It reduces your star count (being a three-star C programmer is not an achievement to be proud of) and simplifies the code. The function should be changed to
int** alloc_matrix( // but what's inside the () ?
The second problem is, why should a function called alloc_matrix prompt the user and read values? These things are not related to allocation. A function should do one thing and do it well. Does malloc prompts you to enter the size? Does fopen prompt you to enter the filename? These things would be regarded as nonsense of the first degree, and rightly so. It is advised to read the sizes elsewhere and pass them to alloc_matrix as input arguments. Hence,
int** alloc_matrix(int n, int m) { // but what's inside the {}?
What remains of alloc_matrix is simple:
int** alloc_matrix(int n, int m) {
int** mat; // that's what we will return
int i;
mat = (int**)calloc(n, sizeof(int*));
for(i = 0; i < n; i++)
// here comes the important part.
Since we have simplified alloc_matrixand reduced the star count in mat, what should we do with the old body of the loop? It was:
*(mat+i) = (int*)calloc(...);
but if we remove a star, it becomes
(mat+i) = (int*)calloc(...);
which is an obvious nonsense. Perhaps the old line was a problem. The fact that it provoked a compiler warning certainly doesn't speak for its correctness. So how to correct it? There aren't too many options. It turns out that in order to restore sanity, we must leave the old left-hand side (written for the three-star mat) intact. Or, better still, use an equivalent but more idiomatic notation:
mat[i] = (int*)calloc(m, sizeof(int));
So the entire function now becomes
int** alloc_matrix(int n, int m) {
int **mat;
int i;
mat = (int**)calloc(n, sizeof(int*));
for(i = 0; i < n; i++)
mat[i] = (int*)calloc(m, sizeof(int));
return mat;
}
and it should be called like
mat = alloc_matrix(n, m);
It is often said that one should not cast the result of calloc and friends. But in this case the cast has enabled a warning which helped to find a bug. I'm leaving the casts in place for now.
There is another idiom for the allocation that does not require the cast, but also avoids the problem of types not matching.
Instead of using the type for the sizeof, you can use the dereferenced pointer as the type information is available in the variable:
mat = (int**)calloc(n, sizeof(int*));
can be changed to
mat = calloc(n, sizeof *mat); //sizeof is an operator not a function

Segmentation fault (core dumped), working with dynamic vectors

package.c:
double * foo(int length) {
int i;
double * a;
a = malloc(sizeof(double) * length)
for(i = 0; i < length; i++ ) {
a[i] = 0.0;
}
return a;
}
main.c
int main(void) {
int i;
double * vector;
vector = foo(999999);
for(i =0;i < 999999; i++) {
printf("%f", vector[i]);
}
return 0
}
What's the problem with my code? I'm getting segmentation fault(core dumped), my dinamic vectors are always with more than 1m elements.
Your main file doesn't contain a declaration for foo. So the compiler assumes the declaration is int foo(), i.e. a function that takes an unknown number of arguments and returns an int.
When compiling you should have gotten a warning similar to this:
warning: implicit declaration of function ‘foo’
warning: assignment makes pointer from integer without a cast
As a result, the return value isn't being captured correctly resulting in undefined behavior, which in this case manifested in a core dump.
Add a prototype to main and that should fix the error.
double * foo(int length);
int main(void) {
...
You should also #include <stdio.h> in main.c and #include <stdlib.h> in package.c and main.c to get the prototypes of printf and malloc respectively.
Also, don't forget to free(vector) at the end of your program to clean up the allocated memory.

How to deal with matrices in C using dynamic memory allocation?

I was trying to run a simulation in which I need to fill three matrices of size "2 x iterations", this is (iterations=)10^8 columns and 2 rows. I also work with a vector t of size 10^8. Using dynamic memory allocation I wrote the following code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define T 10000
#define dt 0.0001
#define iterations (T/dt)
/*(more code)*/
int main(){
int i, j;
double *t;
double (*x)[2], (*y)[2], (*c)[2];
t=(double *) malloc((iterations-1)*sizeof(double));
x=(double (*)[2]) malloc((2*(iterations))*sizeof(double));
y=(double (*)[2]) malloc((2*(iterations))*sizeof(double));
c=(double (*)[2]) malloc((2*(iterations))*sizeof(double));
for(i=0; i=1; i++){
x[i][0]=50+500*i;
y[i][0]=300;
c[i][0]=15;
}
for(j=0; j<=iterations-2; j++){
t[j+1]=t[j]+dt;
/*(more code)*/
printf("%G %G %G %G %G %G\n",x[0][j+1],x[1][j+1],y[0][j+1],y[1][j+1],c[0][j+1],c[1][j+1]);
}
return 0;
}
Is the dynamic memory allocation correctly written? I mean, do I really have a vector t of size "iterations" and the three matrices of size "2 x iterations"?
And, if I want to fill each component of the matrices, for example I want a 50 in the position (1,4) of the matrix x, then do I have to write x[1][4]=50? (Like in the first "for".)
The problem is that executing the program I get an error: segmentation fault. Then, using a debugger I get the following:
Program received signal SIGSEGV, Segmentation fault.
x[0][0]=50
A generic way to allocate a matrix:
double **mat_init(int n_rows, int n_cols)
{
double **m;
int i;
m = (double**)malloc(n_rows * sizeof(double*));
for (i = 0; i < n_rows; ++i)
m[i] = (double*)calloc(n_cols, sizeof(double));
return m;
}
void mat_destroy(int n_rows, double **m)
{
int i;
for (i = 0; i < n_rows; ++i) free(m[i]);
free(m);
}
You can also do this:
double **mat_init2(int n_rows, int n_cols)
{
double **m;
int i;
m = (double**)malloc(n_rows * sizeof(double*));
m[0] = (double*)calloc(n_rows * n_cols, sizeof(double));
for (i = 1; i < n_rows; ++i)
m[i] = m[i-1] + n_cols;
return m;
}
void mat_destroy2(double **m)
{
free(m[0]); free(m);
}
For both methods above, you can use matrix[row][col] to access a cell. Sometimes, you may prefer to allocate a single array and use matrix[row*n_cols+col] to access a cell.
BTW, I am sure someone will say "don't use cast", but there are benefits of using cast – that is off-topic.
I mean, do I really have a vector t of size "iterations"
t=(double *) malloc((iterations-1)*sizeof(double));
^^^
Since you subtract one, the answer is no.
.... and the three matrices of size "2 x iterations"?
Well - yes you have three matrices of size "2 x iterations". However, what you have is equivalent to:
double m[iterations][2];
so you have "iterations" rows and 2 columns.
Remember to always check for "out of memory", i.e.
p = malloc(....);
if (p == NULL)
{
printf("out of mem\n");
return -1;
}
So you access it like:
m[0][0]
m[0][1]
m[1][0]
m[1][1]
m[2][0]
m[2][1]
m[3][0]
......

Resources