The code below works fine when M <= 4, but seems to bugger up if you put in a whole number that's any bigger (in this case, I actually need M to be 10). Does anyone know why this is happening and what can be done about it? Thanks.
/*
"Read all 100 numbers from the text file and store it in a 10x10 array."
*/
#include <stdio.h>
#include <stdlib.h>
FILE *fptr;
int n;
int M = 4; // Length and width of array
int main()
{
// Allocating memory
int **myArray = (int **)malloc(M * sizeof(int));
for (int j = 0; j < M; j++) {
myArray[j] = (int *)malloc(M * sizeof(int));
}
// Loading data into array
fptr = fopen("List of Numbers.txt","r");
for (int i = 0; i < M; i++) {
for (int j = 0; j < M; j++) {
fscanf(fptr,"%d",&n);
// printf("%d ",n);
myArray[i][j] = n;
}
}
fclose(fptr);
// Printing
for (int i = 0; i < M; i++) {
for(int j = 0; j < M; j++) {
printf("%d ",myArray[i][j]);
}
printf("\n");
}
return 0;
}
This line:
int **myArray = (int **)malloc(M * sizeof(int));
should be:
int **myArray = (int **)malloc(M * sizeof(int *));
^
You are allocating an array of pointers, not an array of ints.
Related
I need to return the value of the matrix, but I am gettin this error
Subscripted value is not an array, pointer, or vector
in:
qk_output[m][o] = 0;
and
qk_output[m][o] += queries[m][n] * keys[n][o];
Could anyone help me? Thanks!
int* multmm(int queries[M][N], int keys[N][O]) {
// Matrix Multiplication
int* qk_output = (int*)malloc(sizeof(int) *M*N);
for (int m = 0; m < M; m++) {
for (int o = 0; o < O; o ++) {
qk_output[m][o] = 0;
for (int n = 0; n < N; n++) {
qk_output[m][o] += queries[m][n] * keys[n][o];
}
}
}
return qk_output;
}
To return a 2D array from a function, you can do
#define N 4
#define M 3
int (*foo(void ))[N]
{
int (*p)[N] = malloc(M * sizeof *p);
for (int i = 0; i < M; ++i)
{
for (int j = 0; j < N; ++j)
{
p[i][j] = i + j;
}
}
return p;
}
int main (void){
int (*mat)[N] = foo();
for (int i = 0; i < M; ++i)
{
for (int j = 0; j < N; ++j)
{
printf("%d ", mat[i][j]);
}
puts("");
}
free(mat);
return 0;
}
int* qk_output = (int*)malloc(sizeof(int) *M*N);
qk_output is a pointer to an int
the compiler knows how to access qk_output[n] but doesn't know how to access qk_output[m][n], you need to switch to:
int (*qk_output)[N] = malloc(sizeof(*qk_output) * M); // Don't cast malloc
that is, a pointer to an array of N ints
Now the compiler has enough information to access qk_output[m][n]
For the return question: you can use void *multmm(...) or int (*multmm(...))[N], the second one gives more information to the compiler so it is less error prone.
Something like:
int (*multmm(int queries[M][N], int keys[N][O]))[N]
{
int (*qk_output)[N] = malloc(sizeof(*qk_output) * M);
...
return qk_output;
}
int main(void)
{
int (*arr2D)[N] = multmm(...);
...
}
I'm trying to write a code in C that sum two 4x4 matrix.
But I want my function to have a pointer as my arguments. The only error I'm getting is the time I'm trying to sum up in the function. Could someone help me?
#include <stdio.h>
#include <locale.h>
int i = 0, j = 0;
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
{
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
mat_C[i][j] = mat_A[i][j] + mat_B[i][j];
printf("%d", mat_C[i][j]);
}
}
}
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[4][4], mB[4][4], mC[4][4];
int *mat_A, *mat_B, *mat_C;
for(i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("Type in the value for Matrix A [%d][%d]: ", i, j);
scanf_s("%d", &mA[i][j]);
}
}
i, j = 0;
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
printf("Type in the value for Matrix B [%d][%d]: ", i, j);
scanf_s("%d", &mB[i][j]);
}
}
*mat_A = &mA;
*mat_B = &mB;
return 0;
}
The types of pointers for the arguments are wrong. You want to pass (the pointer to the first elements of) arrays like int mA[4][4];, so they should be pointers to int[4].
void calc_soma(int (*mat_A)[4], int (*mat_B)[4], int (*mat_C)[4])
{
/* same as original */
}
They can simply be written like this:
void calc_soma(int mat_A[][4], int mat_B[][4], int mat_C[][4])
{
/* same as original */
}
Then the function can be called like:
calc_soma(mA, mB, mC);
The purpose of mat_A and mat_B are unclear, but if you want to get pointers to the matrice like &mA, it should be int(*)[4][4]. Note that dereferencing (like *mat_A) uninitialized pointers will invoke undefined behavior.
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[4][4], mB[4][4], mC[4][4];
int (*mat_A)[4][4], (*mat_B)[4][4], (*mat_C)[4][4];
/* omit */
mat_A = &mA;
mat_B = &mB;
return 0;
}
To use functions like
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
you should express the matrice by 1D array to match with the format. It will be like this:
#include <stdio.h>
#include <locale.h>
#define ROWS 4
#define COLS 4
int i = 0, j = 0;
void calc_soma(int* mat_A, int* mat_B, int* mat_C)
{
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
mat_C[i * COLS + j] = mat_A[i * COLS + j] + mat_B[i * COLS + j];
printf("%d", mat_C[i * COLS + j]);
}
}
}
int main()
{
setlocale(LC_ALL, "Portuguese");
int i=0, j=0;
int mA[ROWS * COLS], mB[ROWS * COLS], mC[ROWS * COLS];
for(i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
printf("Type in the value for Matrix A [%d][%d]: ", i, j);
scanf_s("%d", &mA[i * COLS + j]);
}
}
i, j = 0;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
printf("Type in the value for Matrix B [%d][%d]: ", i, j);
scanf_s("%d", &mB[i * COLS + j]);
}
}
calc_soma(mA, mB, mC);
return 0;
}
Here is the code for matrix multiplication of random numbers using rand() function. The output of the program gives very large values as matrix elements.
Why not any small random numbers not generated??
This is the output when N=3
Enter the value of N : 3
Final Matrix :
259448206-96933429-936226671
-409898077185182340844598571
-1916994436-653447116470937338
Program:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main ()
{
time_t t;
int **ptr1, **ptr2, **ptr3;
int N, col1, row2, col2;
srand ((unsigned) time (&t));
int i, j, k;
printf ("\nEnter the value of N : ");
scanf ("%d", &N);
ptr1 = (int **) malloc (sizeof (int *) * N);
ptr2 = (int **) malloc (sizeof (int *) * N);
ptr3 = (int **) malloc (sizeof (int *) * N);
for (i = 0; i < N; i++)
ptr1[i] = (int *) malloc (sizeof (int) * N);
for (i = 0; i < N; i++)
ptr2[i] = (int *) malloc (sizeof (int) * N);
for (i = 0; i < N; i++)
ptr3[i] = (int *) malloc (sizeof (int) * N);
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
ptr1[i][j] = rand ();
}
}
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
ptr2[i][j] = rand ();
}
}
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
ptr3[i][j] = 0;
for (k = 0; k < N; k++)
ptr3[i][j] = ptr3[i][j] + ptr1[i][k] * ptr2[k][j];
}
}
/* Printing the contents of third matrix. */
printf ("\n\nFinal Matrix :");
for (i = 0; i < N; i++) {
printf ("\n\t");
for (j = 0; j < N; j++)
printf ("%4d", ptr3[i][j]);
}
printf ("\n");
return (0);
}
Use the modulo operator to get smaller values (e.g. rand()%100). While it is slightly non-uniformly distributed that way this should not be an issue here. – Ctx
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;
}