how to implement matrix functions in C - c

I am trying to make some simple functions that does some operations on matrixes. But i can`t undestand why the following code is not working!. Can you please help me to understand what is wrong here and what should i do???
void create(int*** p, const int n)
{
*p = (int**)calloc(n, sizeof(int));
if(*p == NULL){
printf("Error1");
}
int i;
for(i = 0; i < n; i++){
(*(p[i]) = (int*)calloc(n, sizeof(int)));
if(*(p[i]) == NULL){
printf("Error2");
}
}
}
void initializeMatrix(int*** p, const int n)
{
int i, j;
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
scanf("%d", &((p[i][j])));
}
}
}
void show(const int** p, const int n)
{
int i, j;
for(i = 0; i < n; i++){
for(j = 0; j < n; j++){
printf("%d ", ((p)[i][j]));
}
printf("\n");
}
}
int main()
{
int** p = NULL;
create(&p, 2);
initializeMatrix(&p, 2);
show(p, 2);
return 0;
}

Problem 1
You are using *(p[i]) in create. it should be (*p)[i].
void create(int*** p, const int n)
{
*p = (int**)calloc(n, sizeof(int));
if(*p == NULL){
printf("Error1");
}
int i;
for(i = 0; i < n; i++){
// FIXED
(*p)[i] = (int*)calloc(n, sizeof(int)));
// FIXED
if( (*p)[i] == NULL){
printf("Error2");
}
}
}
Problem 2
You are passing the wrong size to first calloc in the function. You need to use sizeof(int*). After all, you want the returned value to be a pointer to n pointers to int, not a pointer to n objects of type int.
This is a critical error that leads to undefined behavior unless sizeof(int) is the same as sizeof(int*) on your platform.
Change the line to
*p = (int**)calloc(n, sizeof(int*));
More importantly, you can make that function a bit easier by returning a pointer. It will be easier to write such a function.
int** create(int n)
int **p = calloc(n, sizeof(*p));
if(p == NULL){
printf("Error1");
}
int i;
for(i = 0; i < n; i++){
p[i] = calloc(n, sizeof(*p[i])));
if( p[i] == NULL){
printf("Error2");
}
}
return p;
}
and use it as:
int** p = create(2);

Related

How do I free the memory that I allocated in a defined function later in my main function?

I've been struggling a lot with dynamic allocation and freeing it, and I know that I keep having memory leak issues from this function but I cannot figure out how to have it properly deallocated.
This is the function where t is allocated with malloc and then returned to the main function:
double** transpose(int r, int c , double** arr) {
double** t = (double**) malloc(sizeof(double*) * c);
for (int i = 0; i < c; i++) {
t[i] = (double*) malloc(sizeof(double) * r);
}
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
t[j][i] = arr[i][j];
}
}
return t;
}
And this is the main function that it needs to be freed in at the end. What confuses me is that I know I need to loop through up to the variable c and do free(t[i]), however that variable is out of scope in main since it isn't declared there. So I am not sure how you are supposed to access it to free:
int main (int argc, char** argv){
FILE* fp = fopen(argv[1], "r");
if (fp == NULL) {
printf("error\n");
return 0;
}
fseek (fp, 0, SEEK_END);
if (ftell(fp) == 0) {
return 0;
}
FILE* fp2 = fopen(argv[2], "r");
if (fp2 == NULL) {
printf("error");
return 0;
}
fseek (fp2, 0, SEEK_END);
if (ftell(fp2) == 0) {
return 0;
}
rewind(fp);
rewind(fp2);
int k = 0;
int n = 0;
double z = 0.0;
fscanf(fp, "%d", &k);
fscanf(fp, "%d", &n);
double** x = (double **) malloc(sizeof(double*) * n);
double** y = (double **) malloc(sizeof(double*) * n);
for (int i = 0; i < n; i++) {
x[i] = (double*) malloc((k + 1) * sizeof(double));
y[i] = (double*) malloc(sizeof(double));
for (int j = 0; j < (k + 2); j++) {
if (j == 0) {
x[i][j] = 1;
} else if (j == k + 1) {
fscanf(fp, "%lf", &z);
y[i][0] = z;
} else {
fscanf(fp, "%lf,",&z);
x[i][j] = z;
}
}
}
int m = 0;
fscanf(fp2, "%d", &m);
double** test = (double**) malloc(m * sizeof(double*));
for (int i = 0; i < m; i++) {
test[i] = (double*) malloc((k+1) * sizeof(double));
for (int j = 0; j < (k+1); j++) {
if (j != 0) {
if (j == k+1) {
fscanf(fp2, "%lf", &z);
test[i][j] = z;
}else {
fscanf(fp2, "%lf,", &z);
test[i][j] = z;
}
} else {
test[i][j] = 1;
}
}
}
double** xt = transpose(n, (k+1), x);
double** xxt = multiply((k+1), n, n, (k+1), xt, x);
double** ixxt = inverse(k+1, xxt);
double** ixxtxt = multiply((k+1), (k+1), (k+1), n, ixxt, xt);
double** w = multiply((k+1), n, n, 1, ixxtxt, y);
double** ans = multiply(m, (k+1), (k+1), 1, test, w);
print(m, 1, ans);
fclose(fp);
fclose(fp2);
return 0;
}
Assuming that all the other calculating functions (multiply and so on) don't allocate memory, you can write the following function. It's a design decision to use a separated function to make the code better maintainable.
void release(int c, double** p) {
for (int i = 0; i < c; i++) {
free(p[i]);
}
free(p);
}
Note 1: If the other calculating functions allocate additional memory, you can call release() with the pointers returned by them, too.
Note 2: If the other calculating functions return the same pointer as they receive as argument, you don't really need this, since the values are changed "in place". You can change the return type to void.

Implementing a count sort is crashing my program every time, cannot spot malloc/free error

I've been stuck on this for a while and absolutely cannot find a solution to my problem. I following along Sedgewick's algorithms in C to implement a count sort, but for some reason my b array is not reading the values of my input array correctly, and also crashes the program when trying to free. Any help will be appreciated.
void count_sort(int* a, int l, int r, int M)
{
int i, j;
int* cnt = (int*)malloc(M * sizeof(int));
if (!cnt) {
printf("Returned NULL PTR for cnt\n");
exit(1);
}
int* b = (int*)malloc((r + 1) * sizeof(int));
if (!b) {
printf("Returned NULL PTR for b\n");
exit(1);
}
printf("\n\n\n");
for (j = 0; j < M; ++j)
cnt[j] = 0;
for (i = l; i <= r; ++i)
cnt[a[i]]++;
for (i = 1; i < M; ++i)
cnt[i] += cnt[i - 1];
/*
free(b);
free(cnt);
printf("Able to free here\n");
exit(0);
*/
for (i = l; i <= r; ++i) {
b[cnt[a[i]]] = a[i];
printf("%d\n", b[cnt[a[i]]]);
++cnt[a[i]];
}
/*
free(b);
free(cnt);
printf("Able to free here\n");
exit(0);
*/
for (i = l; i <= r; ++i)
a[i] = b[i - l];
free(cnt);
free(b);
}
int is_sort(int* a, int N)
{
int i;
for (i = 0; i < N - 1; ++i) {
if (a[i + 1] < a[i]) {
printf("%d %d\t%d %d\n", i, a[i], i + 1, a[i + 1]);
return 0;
}
}
return 1;
}
int main(int argc, char** argv)
{
srand(time(NULL));
rand();
int N = atoi(argv[1]);
int M = atoi(argv[2]);
int* arr = (int*)malloc(N * sizeof(int));
int i;
for (i = 0; i < N; ++i) {
arr[i] = ((int)(1000 * (1.0 * rand() / RAND_MAX))) % M;
printf("%d\n", arr[i]);
}
count_sort(arr, 0, N - 1, M);
if (is_sort(arr, N))
printf("sorted\n");
else
printf("not sorted");
free(arr);
return 0;
}
The issue lies in these lines:
for (i = l; i <=r; ++i) {
b[cnt[a[i]]] = a[i];
printf("%d\n", b[cnt[a[i]]]);
++cnt[a[i]];
}
You want to decrement cnt[a[i]], not increment and also you want to do it before the assignment b[cnt[a[i]]] = a[i];, not after.
With these modifications the code works correctly.

*pointer was nullptr* error in C programming

I have a serious problame.
at the line **c = (int*)malloc(size1 * sizeof(int*));
the compiler gives me this error which I don't really know what it says.
Unhandled exception thrown: read access violation.
c was nullptr. occurred
I don't know what I'm doing wrong..
I initialize every pointer like this.
void BuildMatrix(int ***, int, int);
void FreeMatrix(int ***, int);
void PrintMatrix(int **, int, int);
int **MultiplyMatrixes(int **, int**, int, int, int);
int main() {
int **matrix1 = NULL, **matrix2 = NULL, **matrix3 = NULL;
int * newCol = NULL;
int size1, size2, size3, newRow;
printf("-How many rows in the first matrix?: ");
scanf("%d", &size1);
printf("-How many columns in the first matrix and second?[size2, size3]: ");
scanf("%d %d", &size2, &size3); /*size2 = rows of matrix2.*/
/*Build both matrices*/
printf("-First matrix input.\n");
BuildMatrix(&matrix1, size1, size2);
PrintMatrix(matrix1, size1, size2);
printf("-Second matrix input.\n");
BuildMatrix(&matrix2, size2, size3);
PrintMatrix(matrix2, size2, size3);
/*Combine the 2 matrices to a new matrix*/
matrix3 = MultiplyMatrixes(matrix1, matrix2, size1, size2, size3);
FreeMatrix(&matrix2, size2); //Free the second matrix
printf("\n-Multiplied matrix: \n");
PrintMatrix(matrix3, size1, size3);
FreeMatrix(&matrix3, size1);
FreeMatrix(&matrix1, size1);
}
void BuildMatrix(int *** pMat, int row, int col) {
int i, j;
(*pMat) = (int **)malloc(row * sizeof(int*));
if (*pMat == NULL) {
free(pMat);
printf("*Not enough RAM.\nTerminating.\n");
exit(1);
}
for (i = 0; i < row; i++) {
(*pMat)[i] = (int *)malloc(col * sizeof(int*));
if ((*pMat)[i] == NULL) {
printf("*Not enough RAM.\nTerminating.\n");
FreeMatrix(pMat, row);
exit(1);
}
for (j = 0; j < col; j++) {
printf("-Enter %d element in %d row: ", j + 1, i + 1);
scanf("%d", &(*pMat)[i][j]);
}
printf("\n");
}
//FreeMatrix(pMat, row);
}
void PrintMatrix(int ** pMat, int row, int col) {
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
printf("%d ", pMat[i][j]);
}
printf("\n");
}
}
int** MultiplyMatrixes(int ** a, int ** b, int size1, int size2, int size3) {
int i, j, k, **c = NULL;
**c = (int*)malloc(size1 * sizeof(int*));
if (c == NULL) {
free(*c);
printf("*Not enough RAM.\nTerminating.\n");
exit(1);
}
for (i = 0; i < size1; i++) {
for (j = 0; j < size3; j++) {
c[i] = (int *)malloc(size3 * sizeof(int));
if (c[i] == NULL) {
printf("*Not enough RAM.\nTerminating.\n");
FreeMatrix(&c, size1);
exit(1);
}
for (k = 0; k < size2; k++) {
c[i][j] += (a[i][k] * b[k][j]);
}
}
}
return c;
}
(*pMat)[i] = (int *)malloc(col * sizeof(int*));
will be
(*pMat)[i] = malloc(col * sizeof(int));
You have allocated space for col number of int* where you are reading int-s.
Also
**c = (int*)malloc(size1 * sizeof(int*));
will be
c = malloc(size1 * sizeof(int*));
Otherwise you were trying to dereference NULL value which triggered the error you got.
Also the loop will be
for (i = 0; i < size1; i++) {
c[i] = malloc(size3 * sizeof(int));
if (c[i] == NULL) {
printf("*Not enough RAM.\nTerminating.\n");
FreeMatrix(&c, size1);
exit(1);
}
for (j = 0; j < size3; j++) {
c[i][j]=0;
for (k = 0; k < size2; k++) {
c[i][j] += (a[i][k] * b[k][j]);
}
}
}
Don't cast the return value of malloc.

Heap Corruption on resize array by realloc() function in C

I have a problem with increasing C[] array from 6 to 10 I've faced with heap corruption problem by realloc(). I have a following code of Big M metod:
#include <stdio.h>
#include <stdlib.h>
int * mnInit(FILE * );
double * * ReadA(FILE * , int, int);
double * ReadVector(FILE * , int);
int * condtxt(FILE *, int );
void Artif_counter(int* , int *, int);
void reallocationA(double**, int* , int , int);
void increaseA(int*, double**, int, int, int);
void increaseC(double *, int);
int main(int argc, char * argv[]) {
FILE * file1 = fopen("C.txt", "r");
FILE * file4 = fopen("A.txt", "r");
FILE * file5 = fopen("Agetmn.txt", "r");
FILE * file6 = fopen("cond.txt", "r");
int * ptr_mn;
ptr_mn = mnInit(file5);
int n = * (ptr_mn);
int m = * (ptr_mn + 1);
double * * A;
A = ReadA(file4, n, m);
double * C;
C = ReadVector(file1, n);
int * cond;
cond = condtxt(file6, m);
for(int i = 0; i < m; i++){
}
//--------------------------------------------------
int BAcounter = 0;
Artif_counter(cond, &BAcounter, m);
printf("\n Basys and Artifical variable = %d", BAcounter);
reallocationA(A, &n, m, BAcounter);
increaseA(cond, A, n, m, BAcounter);
this function dont't working
increaseC(C, n);
When I trying to print arrays: the A[][] was printed right while C[] array was printed by unknown numbers and after the program Mmetod.exe was closed with problem: A heap has been corrupted (parameters: 0x00007FFCA0C1F6B0).
// count of basys and artif
//------------------------------------------------After Adding a new columns:
printf("\n A[][] ARRAY:\n");
for (int i = 0; i < m; i++) {
printf("%d ", i);
for (int j = 0; j < n; j++) {
printf(" %.3f ", A[i][j]);
}
printf("\n");
}
printf("\n\tVECTOR C[]:\n");
for (int i = 0; i < n; i++) {
printf("%lf ", C[i]);
}
fclose(file1);
fclose(file4);
fclose(file5);
fclose(file6);
free(C);
for (int i = 0; i < m; i++) {
free(A[i]);
}
free(A);
printf("\n\n");
system("pause");
return 0;
}
int * mnInit(FILE * file) {
int c;
int digit = 0;
int column = 0;
int * mnArray = malloc(2 * sizeof( * mnArray));
if (file == NULL) perror("Warning!");
else {
while (!feof(file)) {
c = fgetc(file);
if (c == ';') {
column++;
}
if (c == ' ') {
digit++;
}
}
}
* (mnArray) = (digit / column) + 1; * (mnArray + 1) = column;
return mnArray;
}
double * * ReadA(FILE * file, int n, int m) {
double * * A = malloc(m * sizeof( * A));
for (int i = 0; i < m; i++) {
A[i] = malloc(n * sizeof( * A[i]));
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
//fscanf(file ,"%lf ", &(*(*(A + i) + j)));
fscanf(file, "%lf ", & A[i][j]);
}
fscanf(file, "\n");
}
return A;
}
double * ReadVector(FILE * file, int m) { // ++++
double * Vector = malloc(m * sizeof( * Vector));
for (int i = 0; i < m; i++) {
fscanf(file, "%lf ", Vector + i);
}
return Vector;
}
int* condtxt(FILE * file, int m){
int * condA = malloc(m * sizeof(*condA));
for(int i = 0; i < m; i++){
fscanf(file, "%d", &condA[i]);
}
return condA;
}
void Artif_counter(int * cond, int *k, int m){
for(int i = 0; i < m; i++){
if(cond[i] == -1){
(*k)++;
}
if(cond[i] == 0){
(*k)++;
}
if(cond[i] == 1){
*k = (*k) + 2;
}
}
}
void reallocationA(double** A, int* n, int m, int k){
double * tmp = NULL;
for(int i = 0; i < m; i++){
tmp = realloc(A[i], ((*n) + k)*sizeof(*A[i]));
if(tmp){
A[i] = tmp;
tmp = NULL;
} else{
printf("Error! Memory isn't reallocated'");
tmp = NULL;
}
}
(*n) = (*n) + k;
}
void increaseA(int* cond, double** A, int n, int m, int k){
int presentcol = n-k;
for(int i = 0; i < m; i++){
if(cond[i] == -1){
for(int j = 0; j < m; j++){
if(j == i){
A[j][presentcol] = 1;
} else {
A[j][presentcol] = 0;
}
}
presentcol++;
}
if(cond[i] == 0){
for(int j = 0; j < m; j++){
if(j == i){
A[j][presentcol] = 1;
} else {
A[j][presentcol] = 0;
}
}
presentcol++;
}
if(cond[i] == 1){
for(int j = 0; j < m; j++){
if(j == i){
A[j][presentcol] = 1;
A[j][presentcol + 1] = -1;
} else {
A[j][presentcol] = 0;
A[j][presentcol + 1] = 0;
}
}
presentcol = presentcol + 2;
}
}
}
When I wanted to increase an array in a simple code by this function it've done and I don't understand why(
A GNU debugger rewiev: 0 warning: Critical error detected c0000374
void increaseC(double * C, int n){
double * tmp;
tmp = realloc(C, (n)*sizeof(*C)); // found out that realloc function caused an error
if(!tmp){
printf("Error");
} else{
C = tmp;
}
tmp = NULL;
}

Segmentation fault occurs in the program sometimes, but not always. How do I correct it?

My program compiles without any error, and it also executes fine for some inputs.
But when I give an upper bound input, the .exe file stops working, and no dump file is created.
Please help me out on this one.
#include<stdio.h>
#include<stdlib.h>
#define SIZE 200000
double finval = 32766;
void addf(double st);
void rec(double** tam, long src, long des, double n, double sum);
void op(long u, long v, double** tam, long src, long dest, double n);
int main()
{
double n, m, q;
long c, t, i, j, s, d, u, v, w;
double** mat;
double** tam;
double** qe;
scanf("%lf", &n);
if(n > 0 || n <= SIZE) {
mat = (double **) malloc(n * sizeof(int *));
tam = (double **) malloc(n * sizeof(int *));
for(i = 0; i < n; i++) {
mat[i] = (double *) malloc(n * sizeof(int));
tam[i] = (double *) malloc(n * sizeof(int));
}
}
else
return 1;
scanf("%lf", &m);
if(m <= 0 || m>SIZE)
return 1;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
mat[i][j] = 0;
tam[i][j] = 0;
}
for(i = 0; i < m; i++) {
scanf("%ld %ld %ld", &u, &v, &w);
mat[u][v] = mat[v][u] = w;
}
scanf("%ld %ld", &s, &d);
scanf("%lf", &q);
if(q > 0 || q <= SIZE) {
qe = (double **) malloc(q * sizeof(int *));
for(i = 0; i < q; i++)
qe[i] = (double *) malloc(2 * sizeof(int));
}
else
return 1;
for(i = 0; i < q; i++) {
scanf("%ld %ld", &u, &v);
qe[i][0] = u;
qe[i][1] = v;
}
for(i = 0; i < q; i++) {
for(c = 0; c < n; c++)
for(t = 0; t < n; t++)
tam[c][t] = mat[c][t];
finval = 32766;
op(qe[i][0], qe[i][1], tam, s, d, n);
printf("\n%g", finval);
}
for(i = 0; i < n; i++) {
free(mat[i]);
free(tam[i]);
}
free(tam);
free(mat);
for(i = 0; i < q; i++)
free(qe[i]);
free(qe);
return 1;
}
void op(long u, long v, double** tam, long src, long dest, double n)
{
double sum = 0;
tam[u][v] = tam[v][u] = 0;
rec(tam, src, dest, n, sum);
};
void rec(double** tam, long src, long des, double n, double sum)
{
double que[100], dat;
long front = -1, rear = -1;
long srec, ref;
ref = src;
for(; ref < n; ref++) {
if(tam[src][ref]! = 0) {
que[++rear] = ref;
}
}
if(src == des) {
addf(sum);
return;
}
else
while(front != rear) {
srec = que[++front];
dat = tam[src][srec];
rec(tam, srec, des, n, sum+dat);
}
/*for(i = 0; i < n; i++) {
for(j = 0;j < n;j++)
printf("%lf", tam[i][j]);
printf("\n");
}*/
};
void addf(double st)
{
if(finval > st) {
finval = st;
}
};
I use gcc compiler and I have also tried the gdb debugger, but could not solve the problem.
(double *) malloc(n * sizeof(int));
This is not right. If you wish to allocate room for n double numbers, use malloc(n * sizeof(double)).
when n = SIZE or even near the value of SIZE than you will bloat your memory usage which might case memory overflow and crash your program since you do malloc(n * sizeof(int *)) n times ! so it will be like 200000 memory allocations of size 200000 * sizeof(int) each.
Quicksort is notoriously tricky. In your code nothing prevents i and j to wander off past left and right, so they can very well stray out of your array.

Resources