3d dimensional array with malloc and calloc? - c

I am trying to make an arrangement with dynamic memory, 3-dimensional, my code is as follows:
typedef unsigned char matrix;
matrix ***mat(int n, int b)
{
matrix ***temp = (matrix ***)malloc(n*sizeof(matrix**));
for(int i=0; i<n; i++)
{
temp[i] = (matrix **)malloc(b*sizeof(matrix *));
for(int j = 0; j < b; j++)
temp[i][j]= (matrix *)malloc(b*sizeof(matrix));
}
return temp;
}
int main()
{
matrix ***M2 = mat(3,2);
for(int i=0; i<3; i++)
{
for(int j=0; j<2; j++)
{
for(int k=0; k<2; k++)
{
printf(" %d", M2[i][j][k]);
}
printf("\n");
}
printf("\n");
}
return 0;
}
when I run the program I have a segment violation, someone can tell me what the error is, since I can not visualize

I guess in the most nested for loop (the j one) the variables are messed in declaration for(int j = 0; i < b; i++). Try j for all

Usually I will do this kind of thing in FORTRAN, personally I like write the algorithm involving high dimensional array in FORTRAN as a library, and do the flow control staff in C. While 3D is still easily manageable in C, you need really careful with the pointers, here is a working example, it's valgrind clean.
#include <stdio.h>
#include <stdlib.h>
float ***myarray(int l, int m, int n)
{
float **ptr = malloc(sizeof(float*)*(l+l*m));
float *data = malloc(sizeof(float)*l*m*n);
float **p1 = ptr, **p2 = ptr+l;
for(int i=0; i<l; i++) {
p1[i] = (float*)(p2+i*m);
for(int j=0; j<m; j++)
p2[i*m+j] = data+(i*m+j)*n;
}
return (float***)ptr;
}
void myfree(float ***a)
{
free(a[0][0]);
free(a);
}
int main()
{
float ***array = myarray(4,3,2);
for(int i=0; i<4; i++)
for(int j=0; j<3; j++)
for(int k=0; k<2; k++)
array[i][j][k] = i+j+k;
myfree(array);
return 0;
}

you must correct the j counter inside the nested for loop in mat function, this is the correct one:
for(int j = 0; j < b; j++)

Related

Matrix Multiplication Using double pointers passing into functions in C

I am wondering why I cannot get the value in the function, it always cause segmentation fault...
`
void multiply(int M, int N, int K, int **matrixA, int **matrixB, int **matrixC){
for (int i = 0; i < M; i++){
for (int j = 0; j < K; j++){
int sum = 0;
for (int k = 0; k < N; k++){
sum += (*(*(matrixA + j) + k)) * (*(*(matrixB + k) + j));
}
*(*(matrixC + i) + j) = sum;
}
}
}
int main(){
int M, N, K;
scanf("%d%d%d", &M, &N, &K);
int matrixA[M][N];
int matrixB[N][K];
int matrixC[M][K];
for(int i=0; i<M; i++){
for(int j=0; j<N; j++){
scanf("%d", matrixA[i]+j);
}
}
for(int i=0; i<N; i++){
for(int j=0; j<K; j++){
scanf("%d", matrixB[i]+j);
}
}
multiply(M, N, K, (int **)matrixA, (int **)matrixB, (int **)matrixC);
for(int i=0; i<M; i++){
for(int j=0; j<K; j++){
printf("%d ", matrixC[i][j]);
}
printf("\n");
}
return 0;
}
`
I want to print out the result "matrixC", but in the function, it would cause segmentation fault. I have tried several times, and it seems like it would miss the addresses of the pointer under the double pointers.
Change the prototype of the function multiply to this:
void multiply(int M, int N, int K, int matrixA[M][N], int matrixB[N][K], int matrixC[M][K]);
make your life easier like this (body of function multiply):
for (int i = 0; i < M; i++) { //for each row of matrixA
for (int j = 0; j < K; j++) { //for each column of matrixB
matrixC[i][j] = 0; //set field to zero
for (int k = 0; k < N; k++) { //for each col of A and each row of B
//take the dot product of row i (matrixA) and col j (matrixB)
matrixC[i][j] += matrixA[i][k] * matrixB[k][j];
}
}
}
You have an error in this line
sum += (*(*(matrixA + j) + k)) * (*(*(matrixB + k) + j));
which has been corrected to
matrixA[i][k] //index 'i' not 'j'
The var sum is not needed, therefore opted out.
Based on your comment below
Consider the following code:
int arr[2][2];
int n=0;
for (int i=0; i < 2; ++i) {
for (int j=0; j < 2; ++j) {
arr[i][j] = ++n;
printf("%p (%d) ", &arr[i][j], arr[i][j]);
}
printf("\n");
}
Possible output:
0x7fff7c729470 (1) 0x7fff7c729474 (2)
0x7fff7c729478 (3) 0x7fff7c72947c (4)
As you can see, nicely packed into consecutive integers (basically one array of ints - but that is not guaranteed).
Now have a look at this:
int **parr = (int**) arr;
for (int i=0; i < 2; ++i) {
for (int j=0; j < 2; ++j) {
printf("%p ", *(parr + i) + j);
}
printf("\n");
}
Possible output:
0x200000001 0x200000005
0x400000003 0x400000007
Now, that looks (dangerously) ugly.
As always: pointer != array. Pointer to pointer means, an address of another address, whereas an array is a consecutive block of a type (you could for example take the address of the first element, which is done if the array decays to a pointer).
You have to give the compiler enough information, e.g.
int (*parr)[2] = arr;
See also: https://en.cppreference.com/w/c/language/array#Multidimensional_arrays

Matrix Multiplication function won't compile inside the main

This is a simple matrix multiplication, code won't compile. I also want to take the function outside. I know I have to have global variables and function declaration, but the code won't even compile inside the main.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define N 10
float *A[N], *B[N], *C[N];
int main(){
int count = 0, i,j, k;
for (i = 0; i < N; i++)
A[i] = (float*)malloc(N * sizeof(float));
for (i = 0; i < N; i++)
B[i] = (float*)malloc(N * sizeof(float));
for (i = 0; i < N; i++)
C[i] = (float*)malloc(N * sizeof(float));
for (i = 0; i < N; i++)
for (j = 0; j < N; j++){
A[i][j] = ++count;
B[i][j] = count;
}
void multiply(float* A, float* B, int n) {
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
for(int k=0; k<n; k++)
C[i][j] += A[i][k] * B[k][j];
}
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
printf("%f\t", C[i][j] );
}
Your multiply function definition inside main makes it a nested function which is not allowed in C. You can call as many functions inside a function but cannot define a new function inside an already existing one.
Plus you have also not called the multiply function.
A , B and C are defined at the top as global as an array of pointers to float
inside your multiply function you have locally redefined them as a pointer to a float..
this is why the multiplication fails inside multiply.
you are pretending that A and B are arrays of pointers to float again.. and they have been locally scoped as pointers to float.
Does this do what you were expecting ?
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define N 10
float *A[N], *B[N], *C[N];
void multiply( float *a[], float *b[], float *c[], int n )
{
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
for(int k=0; k<n; k++)
c[i][j] += (a[i][k]) * b[k][j];
}
int main(){
int count = 0, i,j, k;
for (i = 0; i < N; i++)
A[i] = (float*)malloc(N * sizeof(float));
for (i = 0; i < N; i++)
B[i] = (float*)malloc(N * sizeof(float));
for (i = 0; i < N; i++)
C[i] = (float*)malloc(N * sizeof(float));
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
{
A[i][j] = ++count;
B[i][j] = count;
}
multiply(A,B, C, N);
for (i = 0; i < N; i++)
for (j = 0; j < N; j++)
printf("%f\t", C[i][j] );
}
if so please explain it back to me how this works

Matrix columns zeroing, C language

I need to make a little project but I completely don't know how. Im giving matrix A of size n, and it have to return me matrix B which is matrix A with zeroed first and penultimate column. All I did is
#include<stdio.h>
#include<math.h>
int main()
{
int i,n,j,;
int tab[n][n];
printf("Size of matrix:");
scanf("%d",&n);
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
printf("A[%d][%d]=",i,j);
scanf("%lf",&tab[i][j]);
}
printf("Data:");
printf("Matrix A[%d][%d]",n,m);
}
Which I think should let me to type my matrix. What I should do next? Please help me.
There are a lot of errors in your code, the variable m is not declared, the double array is declared with n non-initialized. As the size of matrix is only known at runtime (entered by user), you need to use dynamic memory allocation functions to allocate memory for your matrix.
Try this code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, j, n;
printf("Size of matrix: ");
scanf("%d", &n);
int *tab = (int*)malloc(sizeof(int)*n*n);
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
printf("A[%d][%d]=",i,j);
scanf("%d",(tab+i*n+j));
}
}
for (i = 0; i < n; i++)
{
*(tab+i*n) = 0;
*(tab+i*n+n-2) = 0;
}
//Print tab
for (i = 0; i < n; i++)
{
for (j = 0; j < n; j++)
{
printf("%d ", *(tab+i*n+j));
}
printf("\n");
}
return 0;
}

Output the values of a matrix by passing its pointer to a function

I am trying to send a pointer of a matrix to function for printing the values. However, my following code prints some long numbers so I assumed it prints the addresses instead! How can I print the value of the matrix after passing the pointer of it?
#include <stdio.h>
#include <string.h>
#include <math.h>
void printing(int *edge);
void main(){
int N=3;
int i,j;
int *edge[N];
for (i = 0; i < N; i++){
*(edge+i) = (int *)malloc(N * sizeof(int));
}
srand(0);
for(i = 0; i < N; i++){
for(j = 0; j < N; j++){
if(i == j)
*(*(edge+i)+j) = 0;
else
*(*(edge+i)+j) = 1; //rand() % 10;
}
}
printing(edge); // Pass the pointer of the matrix
}
void printing(int *edge){
int i,j;
int N= 3;
for( i = 0; i < N; i++){
for(j = 0; j < N; j++){
printf("%d \t", ((edge+i)+j)); // I think I have to do something in this line.
}
printf("\n");
}
}
The parameter type of printing is incorrect. It should be int *edge[]. Then when you print, use *(*(edge+i)+j), or better yet edge[i][j].
The result:
void printing(int *edge[]){
int i,j;
int N = 3;
for( i = 0; i < N; i++){
for(j = 0; j < N; j++){
printf("%d \t", edge[i][j]);
}
printf("\n");
}
}
Also, be sure to #include <stdlib.h>, as it's needed for malloc and srand.

Segmentation fault when the program tries write out the results

Greeting,
Somebody can find, why write out these program segmenation fault, when I take in the all inputs?
I don't find where is the problem, or where should be modify my code
And I would like to get the results?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
void inMatrix(int n, double **matrix)
{
int j, i;
for (i = 0; i < n; i++)
{
for (j= 0; j < n; j++)
{
scanf("%lf", &matrix[i][j]);
}
}
}
void inVector(double *vektor, int n)
{
int k;
for (k = 0; k < n; k++)
{
scanf("%lf", &vektor[k]);
}
}
void outVector(double *vektor, int n)
{
int k;
for (k = 0; k < n; k++)
{
printf("%.8lf ", vektor[k]);
}
}
void lup(int n, double **A, double **b, int v)
{
int *Permutation = (int*)malloc(sizeof(int)*n);
int i,j;
int k;
double *max = (double*) malloc (sizeof(double)*n);
int m=0, p=0;
int tmp=0, tmp2=0;
int t=0, isSingular=0;
double largestElement=0.0;
double *helpVector = (double*) malloc (sizeof(double)*n);
double *helpVectorA = (double*) malloc (sizeof(double)*n);
double *helpVectorB = (double*) malloc (sizeof(double)*n);
// for(i=0;i<n;i++)
// {
// for(j=0;j<n;j++)
// {
// A[i][j]=D[i][j];
// }
// }
for(i=0; i<n; i++)
Permutation[i]=i;
for(m=0; m<n-1; m++)
{
for(i=m; i<n; i++)
{
max[i]=fabs(A[i][m]);
}
for(i=m; i<n; i++)
{
if(max[i]>largestElement)
{
largestElement=max[i];
p=i;
}
}
for(i=0; i<n; i++)
{
helpVectorA[i]=A[m][i];
helpVectorB[i]=A[p][i];
}
for(i=0; i<n; i++)
{
A[m][i]=helpVectorB[i];
A[p][i]=helpVectorA[i];
}
tmp=Permutation[m];
tmp2=Permutation[p];
Permutation[m]=tmp2;
Permutation[p]=tmp;
if(fabs(A[m][m])>0.00000000000000001)
{
for(i=m+1; i<n; i++)
{
A[i][m]=A[i][m]/A[m][m];
for(j=m+1; j<n; j++)
{
A[i][j]=A[i][j]-A[i][m]*A[m][j];
}
}
}
if(fabs(A[m][m])<0.00000000001)
{
printf("szingularis\n");
isSingular=1;
break;
}
for(i=0; i<n; i++) max[i]=-1;
largestElement=0.0;
p=m+1;
}
if(isSingular==0)
{
if(fabs(A[n-1][n-1])<0.00000000001)
{
printf("szingularis\n");
isSingular=1;
}
}
if(isSingular==0)
{
for(k=0; k<v;k++)
{
for(i=0; i<n; i++)
{
t=Permutation[i];
helpVector[i]=b[k][t];
}
for(i=0; i<n; i++)
{
b[i][k]=helpVector[i];
}
for(i=1; i<n; i++)
{
for(j=0; j<i; j++)
{
b[k][i]-=A[i][j]*b[k][j];
}
}
for(i=n-1; i>=0; i--)
{
for(j=i+1; j<n; j++)
{
b[k][i]-=A[i][j]*b[k][j];
}
b[k][i]=b[k][i]/A[i][i];
}
}
for(i=0; i<n; i++)
{
printf("%.8lf ", b[k][i]);
}
printf("\n");
}
}
int main()
{
int k, v,n;
int j;
double **A;
double **C;
// read dimension of matrix and value
scanf("%d", &n);
//matrix
A = (double **) calloc(n, sizeof ( double*));
// matrix to store the vectors
C = (double **) calloc(n, sizeof(double *));
while(n!=0)
{
for (k = 0; k < n; k++)
{
A[k] = (double *) calloc(n, sizeof ( double));
}
inMatrix(n, A);
scanf("%d", &v);
for(k=0;k<v;k++)
{
C[k] = (double *) calloc(n, sizeof ( double));
}
for(k=0; k<v;k++)
{
for(j=0;j<n;j++)
{
scanf("%lf", &C[k][j]);
}
}
//print out result
for(k=0;k<v;k++)
{
for(j=0;j<v;j++)
{
lup(n,A,C,v);
}
}
}
return 0;
}
In main, you have
/* ... */
C = (double **) calloc(n, sizeof(double *));
n elements
while(n!=0)
{
for (k = 0; k < n; k++)
{
A[k] = (double *) calloc(n, sizeof ( double));
}
inMatrix(n, A);
scanf("%d", &v);
for(k=0;k<v;k++)
v? Where did it come from? Do you perhaps mean n
Remember C was allocated space for n elements, even before v was set.
{
C[k] = (double *) calloc(n, sizeof ( double));
}
/* ... */
Your indentation and use of whitespace could improve a bit too.
In function lup, at line 157 (in the second "if(isSingular==0)" block) you wrote
printf("%.8lf ", b[k][i]);
this line is written in a for-loop iterating on i, while k has a leftover value from the last loop. The break condition of that loop was that k = v (the size of C, A.K.A "b" from the line of code above).
So, basically, you wrote:
printf("%.8lf", b[MaxIndexOfB+1][i];
And that's probably the stinker you're looking for.
Two notes. First, I've been .Net man for too long, so I might be missing something completely trivial here, In that case, sorry.
Second, when you want people to read your code (like when posting it for help), it's imperative to use more meaningful names, or something to improve code readability, but if you're not going to do this, at least avoid confusing stuff like passing variable named "C" into parameter named "b" if it's avoidable.
Checkout this tutorial. It teaches you how to find segfaults using GDB.

Resources