i have this small piece of code which i cant get to work.
I am kinda new and i just cant find a mistake i did. Thanks
int main (void)
{
int **array;
int i,j, m;
scanf("%d", &m);
array = malloc(sizeof(int) * (m*m));
for (i = 0; i < m; i++)
{
for (j = 0; j < m; j++)
{
scanf("%d", &array[i][j]);
}
}
for (i = 0; i < m; i++)
{
for (j = 0; j < m; j++)
{
printf("%d", array[i][j]);
}
}
return 0;
}
What you are allocating is an one dimensional array of size m*m but you are using it as if you have allocated a jagged array where each row contains m elements.
You can allocate a bit different way than what you did
array = malloc(sizeof *array * m);
if( array == NULL)
{
// error in malloc
}
for(size_t i =0; i<m; i++)
{
array[i]= malloc(sizeof *array[i] * m);
if( array[i] == NULL)
{
// error
}
}
...
for(size_t i = 0; i<m ; i++)
free(array[i]);
free(array);
Alternatively you can put all the elements in a linear manner using i and j.
int *array;
...
for (i = 0; i < m; i++)
{
for (j = 0; j < m; j++)
{
if( scanf("%d", &array[i*m+j]) != 1){
// error in getting input.
}
}
}
...
free(array);
Same goes with printf also.
Also don't forget to free the memory you have allocated dynamically after you are done working with it.
Related
I am really new to C and this is for a school assignment.
So, I am tasked to transpose a given matrix.
My current function is the following:
void matrixTranspose(int rows, int cols, int **array) {
int temp[rows][cols];
int i, j;
for (i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
temp[i][j] = array[i][j];
}
}
array = realloc(array, cols * sizeof(int *));
for (i = 0; i < cols; i++) {
array[i] = realloc(array[i], rows * sizeof(int));
}
for (i = 0; i < cols; i++) {
for(j = 0; j < rows; j++) {
array[i][j] = temp[j][i];
}
}
}
If I introduce equal values for columns and rows or if the value of rows is bigger than the value of columns it works fine, but for some reason when the value of rows is smaller than the value of columns, it does not works. (Throws me "Segmentation fault (core dumped)" error).
My main looks like this:
int main() {
int **mat;
int cols, rows;
int i, j;
printf("Enter number of rows\n");
scanf("%d", &rows);
printf("Enter number of columns\n");
scanf("%d", &cols);
mat = (int **) malloc (sizeof(int *) * rows);
for (i = 0; i < rows; i++) {
mat[i] = (int *) malloc (sizeof(int) * cols);
}
for (i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
mat[i][j] = rand() % 10;
}
}
printf("\nBefore transpose: \n");
for (i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
matrixTranspose(rows, cols, mat);
printf("\nAfter transpose: \n");
for (i = 0; i < cols; i++) {
for(j = 0; j < rows; j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
I hope I explained myselft correctly, sorry for my english, it is not my first language. Thanks
When you modify array in matrixTranspose, you're changing a local variable. That change isn't visible in the calling function, so mat in main no longer points to valid memory.
You need to change the function to accept address of a int ** and dereference it as needed.
void matrixTranspose(int rows, int cols, int ***array) {
int temp[rows][cols];
int i, j;
for (i = 0; i < rows; i++) {
for(j = 0; j < cols; j++) {
temp[i][j] = (*array)[i][j];
}
}
*array = realloc(*array, cols * sizeof(int *));
if (!*array) {
perror("realloc failed");
exit(1);
}
int min = rows < cols ? rows : cols;
for (i = 0; i < min; i++) {
(*array)[i] = realloc((*array)[i], rows * sizeof(int));
if (!(*array)[i]) {
perror("realloc failed");
exit(1);
}
}
if (rows > cols) {
for (i = min; i < rows; i++) {
free((*array)[i]);
}
} else if (cols > rows) {
for (i = min; i < cols; i++) {
(*array)[i] = malloc(rows * sizeof(int));
if (!(*array)[i]) {
perror("malloc failed");
exit(1);
}
}
}
for (i = 0; i < cols; i++) {
for(j = 0; j < rows; j++) {
(*array)[i][j] = temp[j][i];
}
}
}
Note that if the number of rows and columns are not the same, you'll need to either free the extra rows you no longer have or use malloc to allocate new rows.
Note also that you should be checking the return value of malloc and realloc for failure.
Then pass the address of mat to this function:
matrixTranspose(rows, cols, &mat);
You can change the transpose function like this:
int ** matrixTranspose(int rows, int cols, int **array) {
...
return array;
}
And then in main call it like this:
mat = matrixTranspose(rows, cols, mat);
Apart from that, I recommend these thanges. I have changed the argument to sizeof to be the actual variable instead of the type.
array = realloc(array, cols * sizeof(*array));
for (i = 0; i < cols; i++) {
array[i] = realloc(array[i], rows * sizeof(*array[0]));
}
and
mat = (int **) malloc (sizeof(*mat) * rows);
for (i = 0; i < rows; i++) {
mat[i] = (int *) malloc (sizeof(*mat[0]) * cols);
}
Your array is passed by value (i.e. you don't pass a pointer to your matrix). Yet you change it.
array = realloc(array, cols * sizeof(int *));
This is just a local change. Also,
for (i = 0; i < cols; i++) {
array[i] = realloc(array[i], rows * sizeof(int));
}
If rows < col this piece of code will try to reallocate memory for array[i] where i>rows-1. That implies deallocating the memory pointed to by array[i] has never been allocated and you have no idea where it points to.
I am tasked to transpose a given matrix.
Key problem: Code passed the pointer by value and matrixTranspose() need to receive its address in order to modify it. Well answered by others without changing much.
Yet consider a larger change instead. Do not modify the original matrix, make a transposed copy and free matrix helper functions.
int **matrixTranspose_copy(int rows, int cols, const int **array) {
int **transpose = malloc(sizeof *transpose * cols);
for (int r = 0; r < cols; r++) {
transpose[r] = malloc(sizeof *transpose[r] * rows);
for(int c = 0; c < rows; c++) {
transpose[r][c] = array[c][r];
}
}
}
return transpose;
}
void matrixFree(int rows, const int **array) {
for (int r = 0; r < rows; r++) {
free(array[r]);
}
free(array);
}
void matrixTranspose_inplace(int rows, int cols, int ***array) {
int **original = *array;
*array = matrixTranspose_copy(rows, cols, original);
matrixFree(original);
}
I have to write a program which multiply matrix using pointers.
My program does it correctly, but there are two problems:
1) I can do only one multiplication - when I want next one there is error
2) when I input data of first and second matrix i have to put one more
char to make my program work.
What should I change in my code to solve those problems?
#include <stdio.h>
#include <stdlib.h>
while (z--) { // the number of sets
scanf ("%d %d", &n1, &m1); // first matrix n1 x m1
int **A = malloc(n1 * sizeof(int*));
for (i = 0; i < n1; i++) {
*(A+i) = malloc(m1 * sizeof(int));
}
for (i = 0; i < n1; i++) {
for (j = 0; j < m1; j++) {
scanf("%d ", (A+i*m1+j));
}
}
scanf("%d %d", &n2, &m2); // second matrix n2 x m2
int **B = malloc(n2 * sizeof(int*));
for (i = 0; i < n2; i++) {
*(B+i) = malloc(m2 * sizeof(int));
}
for (i = 0; i < n2; i++) {
for (j = 0; j < m2; j++) {
scanf("%d ", (B+i*m2+j));
}
}
if (m1 != n2) {
printf ("ERROR\n");
} else {
int **C = malloc(n1 * sizeof(int*)); //matrix with product
for (i = 0; i < n1; i++) {
*(C+i) = malloc(m2 * sizeof(int));
}
for (i=0; i<n1; i++) {
for (j=0; j<m2; j++) {
*(C+i*m2+j) = 0;
}
}
for (k = 0; k < n2; k++) {
for (i = 0; i < n1; i++) {
for (j = 0; j < m2; j++) {
C1 = 0;
A1 = *(A+i*m1+k);
B1 = *(B+k*m2+j);
C1 = (C1+A1*B1)%1000;
temp = *(C+i*m2+j);
*(C+i*m2+j) = temp+C1;
}
}
}
for (i = 0; i < n1; i++) {
for (j = 0; j < m2; j++) {
printf("%d ", *(C+i*m2 +j));
}
printf("\n");
}
for (i = 0; i < n1; i++) { // free third matrix
free(*(C+i));
}
free(C);
}
for (i = 0; i < n1; i++) { // free first matrix
free(*(A+i));
}
free(A);
for (i = 0; i < n2; i++) { // free second matrix
free(*(B+i));
}
free(B);
}
return 0;
You write to memory beyond the allocated size. This invokes undefined behavior, a good explanation for the erratic behavior you observe.
The offending code is this:
for (k=0; k<n2; k++){
for (i=0; i<n1; i++) {
for (j=0; j<m2; j++) {
C1=0;
A1=*(A+i*m1+k);
B1=*(B+k*m2+j);
C1=(C1+A1*B1)%1000;
temp=*(C+i*m2+j);
*(C+i*m2+j)=temp+C1;
}
}
}
You assume that the matrices are allocated as a single packed 2D array.
Since you allocate them as arrays of pointers to arrays of int, you cannot use this code. Use the much simpler version below:
for (k = 0; k < n2; k++){
for (i = 0; i < n1; i++) {
for (j = 0; j < m2; j++) {
C[i][j] += A[i][k] * B[k][j] % 1000;
}
}
}
It is not clear why you compute modulo 1000. If you really mean that, you should use this:
C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % 1000;
If you are not supposed to use the [] syntax, replace it with the equivalent for pointer dereferencing, not 2D array addressing. I understand what they are trying to teach you, but a diagram would be more effective than this.
*(*(C+i)+j) = (*(*(C+i)+j) + *(*(A+i)+k) * *(*(B+k)+j)) % 1000;
As you may have noticed, the [] syntax is the same for 2D arrays and arrays of pointers to arrays, but the code generated for pointer arithmetic and dereferencing is quite different.
There are other places where you need to change the indexing method, here is the corrected code:
while (z--) { // the number of sets
scanf("%d %d", &n1, &m1); // first matrix n1 x m1
int **A = malloc(n1 * sizeof(int*));
for (i = 0; i < n1; i++) {
*(A+i) = malloc(m1 * sizeof(int));
for (j = 0; j < m1; j++) {
scanf("%d ", *(A+i)+j);
}
}
scanf("%d %d", &n2, &m2); // second matrix n2 x m2
int **B = malloc(n2 * sizeof(int*));
for (i = 0; i < n2; i++) {
*(B+i) = malloc(m2 * sizeof(int));
for (j = 0; j < m2; j++) {
scanf("%d ", *(B+i)+j);
}
}
if (m1 != n2) {
printf ("ERROR\n");
} else {
int **C = malloc(n1 * sizeof(int*)); //matrix with product
for (i = 0; i < n1; i++) {
// using calloc so matrix is initialized to 0
*(C+i) = calloc(m2, sizeof(int));
}
for (k = 0; k < n2; k++) {
for (i = 0; i < n1; i++) {
for (j = 0; j < m2; j++) {
*(*(C+i)+j) = (*(*(C+i)+j) + *(*(A+i)+k) * *(*(B+k)+j)) % 1000;
}
}
}
for (i = 0; i < n1; i++) {
for (j = 0; j < m2; j++) {
printf("%d ", *(*(C+i)+j));
}
printf("\n");
}
for (i = 0; i < n1; i++) { // free third matrix
free(*(C+i));
}
free(C);
}
for (i = 0; i < n1; i++) { // free first matrix
free(*(A+i));
}
free(A);
for (i = 0; i < n2; i++) { // free second matrix
free(*(B+i));
}
free(B);
}
return 0;
int main()
{
double *array;
long int n;
n=10000000;//10^7
array = (double *) malloc(n*sizeof(double));
return 0;
}
basically, I want to use this code for a really big aray into a 2 dimensional array, which will have dimensions [very large][4].
If you want a 2D array, then allocate a 2D array. It's that simple.
double (*pArr)[4] = malloc(10000000 * sizeof pArr[0]);
Notes:
do not cast the return value of malloc().
use sizeof pArr[0] instead of sizeof(TheDataType) for defensive programming reasons.
This seems working on Wandbox.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double (* array)[4];
long int n;
int i, j;
n=10000000;//10^7
array = (double (*)[4]) malloc(n*sizeof(double[4]));
printf("%u\n",(unsigned int)sizeof(array[0]));
printf("%u\n",(unsigned int)sizeof(double[4]));
for (i = 0; i <n; i++) {
for (j = 0; j < 4; j++) array[i][j] = (double)i * j;
}
for (i = 0; i < 10; i++) {
for (j = 0; j < 4; j++) printf("%f ", array[i][j]);
putchar('\n');
}
for (i = n - 10; i < n; i++) {
for (j = 0; j < 4; j++) printf("%f ", array[i][j]);
putchar('\n');
}
free(array);
return 0;
}
int n = 100000;
double** array = malloc(sizeof(double*)*n);
for (int i = 0; i < n; ++i)
{
array[i] = malloc(4*sizeof(double));
}
Also note that we don't cast the malloc's result(Do I cast the result of malloc?).
I'm working on a project (written in C) involving matrix factorization and I need some help.
My objective is to allocate memory for an upper triangular matrix and I want to access it via algebraic row and column notation (i.e. i,j in {1,2,...,n} instead of i,j in {0,1,...,n-1}).
For example, in a 5x5 matrix I should be able to access the [3][4] element if I input matrix[3][4].
My code for a non-algebraic index upper triangular matrix looks like this:
double** malloc_sup_matrix (int n)
{
double** L;
int i;
L = (double**)malloc((n)*sizeof(double*));
if(L == NULL)
printerror("allocating space for the matrix (rows).");
for(i = 0; i < n; i++)
{
L[i] = (double*)malloc((n-i)*sizeof(double));
if(L[i] == NULL)
printerror("allocating space for the matrix (cols).");
L[i]-=i;
}
return L;
}
My code for the algebraic index one (I'm not checking if the allocated space is null yet, I'll do it when I stop messing around with this):
int** m;
int i, n;
n = 10;
m = (int**)malloc((n+1)*sizeof(int*));
for(i = 0; i < n; i++)
{
m[i] = (int*)calloc((n+1)-(i),sizeof(int));
m[i] -= i;
}
m--;
for(i = 0; i < n; i++)
{
m[i]--;
}
It works just the way I want it, but I have issues when freeing the space I've used. This is the way I'm doing it:
for(i = 1; i <= n; i++)
{
m[i]++;
}
for(i = 0; i < n; i++)
{
m[i] += (i);
free(m[i]);
}
m++;
free(m);
Do you guys have any suggestions? Thank you so much in advance ^^.
There's a problem on this line:
m--;
for(i = 0; i < n; i++)
{
m[i]--;
}
You're decrementing m, but then go ahead and index it from 0 ... I guess you may end up messing up the heap structures.
I managed to have your code valgrind error-free like this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int** m;
int i, j, n;
n = 10;
m = (int**)malloc((n+1)*sizeof(int*));
for(i = 0; i < n; i++)
{
m[i] = (int*)calloc((n+1)-(i), sizeof(int));
m[i] -= i;
}
for(i = 0; i < n; i++)
{
m[i]--;
}
m--;
/* Access it like m[1][1] ... m[n][n], m[i][j] (with i <= j) */
/*
for (i = 1; i <= n; i++) {
for (j = i; j <= n; j++) {
m[i][j] = i+j;
}
}
*/
m++;
for(i = 0; i < n; i++)
{
m[i]++;
}
for(i = 0; i < n; i++)
{
m[i] += (i);
free(m[i]);
}
free(m);
return 0;
}
I get a segmentation fault when running this code. Anyone know why? Thanks.
#include <stdio.h>
int main()
{
double **m1, **m2, **mr;
int m1_rows, m1_cols, m2_rows, m2_cols, mr_rows, mr_cols;
int i, j, k;
printf("Enter number of rows for matrix 1: ");
scanf("%d", &m1_rows);
printf("Enter number of columns for matrix 1: ");
scanf("%d", &m1_cols);
printf("Enter number of rows for matrix 2: ");
scanf("%d", &m2_rows);
printf("Enter number of columns for matrix 2: ");
scanf("%d", &m2_cols);
//allocate memory for matrix 1 m1
m1 = (double **) calloc(m1_rows, sizeof(double *));
for (i = 0; i < m1_rows; i++) {
m1[i] = (double *) calloc(m1_cols, sizeof(double));
}
//allocate memory for matrix 2 m2
m2 = (double **) calloc(m2_rows, sizeof(double *));
for (i = 0; i < m2_rows; i++) {
m2[i] = (double *) calloc(m2_cols, sizeof(double));
}
//allocate memory for sum matrix mr
mr = (double **) calloc(mr_rows, sizeof(double *));
for (i = 0; i < mr_rows; i++) {
mr[i] = (double *) calloc(mr_cols, sizeof(double));
}
//assign mr_rows and mr_cols
mr_rows = m1_rows;
mr_cols = m2_cols;
//initialize product matrix
for (i = 0; i < m1_rows; i++) {
for (j = 0; j < m2_cols; j++) {
mr[i][j] = 0;
}
}
//perform matrix multiplication
for (i = 0; i < m1_rows; i++) {
for (j = 0; j < m2_cols; j++) {
mr[i][j] = 0;
for (k = 0; k < m1_cols; k++) {
mr[i][j] += m1[i][k] * m2[k][j];
}
}
}
//print result
for (i = 0; i < mr_rows; i++) {
for (j = 0; j < mr_cols; j++) {
printf("%f\t", mr[i][j]);
}
}
//free memory m1
for (i = 0; i < m1_rows; i++); {
free(m1[i]);
}
free(m1);
//free memory m2
for (i = 0; i < m2_rows; i++); {
free(m2[i]);
}
free(m2);
//free memory mr
for (i = 0; i < mr_rows; i++); {
free(mr[i]);
}
free(mr);
return 0;
}
I ran using valgrind valgrind --tool=memcheck a.out for more info on the segmentation fault, but the result was over 30000 errors so it didn't print them out.
You are not assigning mr_rows and mr_cols. They need to be set like this:
mr_rows = m1_rows;
mr_cols = m2_cols;
This line is no good:
mr[i][j] += m1[i][k] * m2[k][j];
That will be accessing elements out of bounds, not least because k is not initialized. You need that line of code inside three nested for loops. Indeed, you may as well roll the zeroising code into this too.
for(i=0; i<m1_rows; i++){
for(j=0; j<m2_cols; j++){
mr[i][j] = 0;
for(k=0; k<m1_cols; k++){
mr[i][j] += m1[i][k]*m2[k][j];
}
}
}
Also, all your memory freeing loops are wrong. Instead of
for(i=0; i<m1_rows; i++);{
free(m1[i]);
}
free(m1);
it should read
for(i=0; i<m1_rows; i++){
free(m1[i]);
}
free(m1);
That stray semicolon was killing you.
You also need to perform a check that the number of columns in m1 equals the number of rows in m2, i.e. test that m1_cols == m2_rows.
One final point. You duplicate your code horribly here. Don't have three identical for loops to allocate a matrix and three identical for loops to deallocate. Extract those operations into helper functions which can be called from main.
That's all that I can find!
You are not assigning any values to mr_rows and mr_cols anywhere. So they will have junk values and you use them to to allocate memory by callin calloc().