Just as the title says, here I ask for two inputs in order to generate a matrix based on such inputs from the user, which then will be filled with random numbers up to the number 20.The problem is I can't wrap my head around the logic needed to generate an exact copy of this matrix without generating a second matrix with randomly generated numbers(again) so I can make useof the data stored in the copy.
(Edit)
I've added an image as reference of what I'm trying to achieve.
I tried to store the random values in a one dimensional array, so I can use them later, but I'm not sure if it is the right approach. I'm relatively new to coding and still struggling with the basics, so any help will be greatly appreciated.
Here´s the code that generates the matrix and stores random int values in it.
#include <stdio.h>
#include<time.h>
int matrizAleatoria(int m, int n, int r);
int srand();
int rand();
int main()
{
int m, n;
printf("Introduce el numero de filas:\n");
scanf("%d", &m);
printf("Introduce el numero de columnas:\n");
scanf("%d", &n);
printf("\n");
srand(time(0));
int r = (rand()% 20);
matrizAleatoria(m, n, r);
printf("\n");
return 0;
}
int matrizAleatoria(int m, int n, int r)
{
int i, j, p = m * n;
int matriz1[m][n];
int serie[p];
for(i = 0; i<m; i++)
{
for(j = 0; j<n; j++)
{
matriz1[i][j] = r = (rand()% 20);
serie[i] = r;
printf("[ %-2d ] " , matriz1[i][j]);
}
printf("\n");
}
return serie[i];
}
You cannot return a variable-sized array from a function to outside scope. You have to implement 2-dimensional subscripts yourself and only work with pointers. Like this:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define SUBSCRIPT_2DIM_TO_1DIM(subscript1, subscript2, size2) \
((subscript1) * (size2) + (subscript2))
int* matrizAleatoria(int m, int n);
int main()
{
int m, n;
int* matriz1;
printf("Introduce el numero de filas:\n");
scanf("%d", &m);
printf("Introduce el numero de columnas:\n");
scanf("%d", &n);
printf("\n");
srand(time(0));
matriz1 = matrizAleatoria(m, n);
printf("\n");
// use matriz1 with SUBSCRIPT_2DIM_TO_1DIM
free(matriz1);
return 0;
}
int* matrizAleatoria(int m, int n)
{
int i, j, p = m * n;
// return matrix value, must free() in the caller
int *matriz1 = malloc(sizeof(int) * p);
for(i = 0; i<m; i++)
{
for(j = 0; j<n; j++)
{
matriz1[SUBSCRIPT_2DIM_TO_1DIM(i, j, n)] = rand()% 20;
printf("[ %-2d ] " , matriz1[SUBSCRIPT_2DIM_TO_1DIM(i, j, n)]);
}
printf("\n");
}
return(matriz1);
}
Related
I am new to C coding, and am trying to implement standard matrix multiplication. My code works fine for square matrices, but refuses to accept a column vector. Here is my attempt at the code. Any help would be much appreciated.
//---------------------------------------IMPORTING NECESSARY C PACKAGES AND DEFINING EXECUTION CONSTANTS-------------------------------------------//
#include <stdio.h> // Standard input output library
#include <math.h> // Mathematical function library
#include <stdlib.h> // General purpose standard library
#define true 1
#define false 0
typedef long double numeric; // Using the long double datatype to avoid overflows during computations
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------------------FUNCTION DECLERATION-------------------------------------------------------------//
numeric **create_matrix(int x, int y); // To dynamically allocate memory and create a matrix
void input_matrix(numeric **matrix, int m, int n); // To accept a matrix
void print_matrix(numeric **l, int x, int y); // To print a matrix
numeric **standard_matrix_multiplication(int m, int n, int l); // To multiply two matrices
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//------------------------------------------------------------------DRIVER CODE--------------------------------------------------------------------//
int main(int argc, char *argv[]) {
int m, n, l; int choice;
printf("Enter the matrix operation to be performed using the corresponding index number.\n");
printf("\n");
printf("1.\tMatrix Multiplication");
printf("\n");
scanf("%d", &choice);
switch(choice) {
case 1 :
printf("Enter the number of rows in the first matrix\n");
scanf("%d", &m);
printf("Enter the number of columns in the first matrix\n");
scanf("%d", &n);
printf("Enter the number of columns in the second matrix\n");
scanf("%d", &l);
printf("Enter both matrices.\n");
numeric **matrix_x;
matrix_x = create_matrix(m, l);
matrix_x = standard_matrix_multiplication(m, n, l);
print_matrix(matrix_x, m, l);
break;
}
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------------MATRIX MULTIPLICATION IMPLEMENTATIONS--------------------------------------------------//
numeric **standard_matrix_multiplication(int m, int n, int l) {
numeric **matrix_a; numeric **matrix_b; numeric **matrix_k;
matrix_a = create_matrix(m, n);
matrix_b = create_matrix(n, l);
matrix_k = create_matrix(m, l);
input_matrix(matrix_a, m, n);
print_matrix(matrix_a, m, n);
input_matrix(matrix_b, n, l);
for(int i = 0; i < m; i++) {
for (int j = 0; j < n; j ++) {
for (int k = 0; k < l; k++) {
matrix_k[i][j] += matrix_a[i][k] * matrix_b[k][j];
}
}
}
return matrix_k;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------HELPER FUNCTIONS------------------------------------------------------------------//
numeric **create_matrix(int x, int y) {
numeric **matrix = (numeric**)malloc(x * sizeof(numeric*)); // Dynamically creating an array of pointers
for (int i = 0; i < y; i++) {
matrix[i] = (numeric*)malloc(y * sizeof(numeric)); // Dynamically allocating memory for each columns of the matrix
}
return matrix;
}
void input_matrix(numeric **matrix, int m, int n) {
printf("Enter the elements of the matrix, row wise.\n"); // Instructing the user on matrix entry
printf("For example, to enter the matrix\n");
printf("\t\t1\t2\n");
printf("\t\t3\t4\n");
printf("enter 1, 2, 3, and 4 in that order.\n");
for (int i = 0; i < m; i++) { // Iterating through the rows and columns of the matrix
for (int j = 0; j < n; j++) {
scanf("%Lf", &matrix[i][j]); // Accepting each element
}
}
}
void print_matrix(numeric **l, int x, int y) { // To print a matrix
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
printf("%0.10Lf\t", l[i][j]); // Printing numeric type values
}
printf("\n");
}
printf("\n");
}
As of now, I have only written one switch case, and that is for matrix multiplication. So I chose 1. I gave 2, 1, 2 as my inputs for the number of rows in the first matrix, number of columns in the first matrix, and number of columns in the second matrix respectively. I have given a print statement in line 52, and it isn't executing it for the above input, giving a segmentation fault instead. Could someone please help me out?
Yes there are some issues with your code that gives segfault error during runtime.
The Matrix multiplication logic part of the code needs to be corrected as follows
for(int i = 0; i < m; i++) {
for (int j = 0; j < l; j ++) {
for (int k = 0; k < n; k++) {
matrix_k[i][j] += matrix_a[i][k] * matrix_b[k][j];
because k should iterate till the no of columns in 1st matrix which is n but not till l.
And there is a slight correction needed in create_matrix function.
You use y (i.e. no of columns in the matrix) in your for instead of x (no of rows in matrix).
If x < y, you end up outside of the memory you allocated.
If x > y, you end up with uninitialized pointers.
So change it as follows
for (int i = 0; i < x; i++) {
matrix[i] = (numeric*)malloc(y * sizeof(numeric));
After these corrections try executing the code, you should get the expected results without any segfault errors
Here is the complete working code
#include <stdio.h> // Standard input output library
#include <math.h> // Mathematical function library
#include <stdlib.h> // General purpose standard library
#define true 1
#define false 0
typedef long double numeric; // Using the long double datatype to avoid overflows during computations
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------------------FUNCTION DECLERATION-------------------------------------------------------------//
numeric **create_matrix(int x, int y); // To dynamically allocate memory and create a matrix
void input_matrix(numeric **matrix, int m, int n); // To accept a matrix
void print_matrix(numeric **l, int x, int y); // To print a matrix
numeric **standard_matrix_multiplication(int m, int n, int l); // To multiply two matrices
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//------------------------------------------------------------------DRIVER CODE--------------------------------------------------------------------//
int main(int argc, char *argv[]) {
int m, n, l; int choice;
printf("Enter the matrix operation to be performed using the corresponding index number.\n");
printf("\n");
printf("1.\tMatrix Multiplication");
printf("\n");
scanf("%d", &choice);
switch(choice) {
case 1 :
printf("Enter the number of rows in the first matrix\n");
scanf("%d", &m);
printf("Enter the number of columns in the first matrix\n");
scanf("%d", &n);
printf("Enter the number of columns in the second matrix\n");
scanf("%d", &l);
printf("Enter both matrices.\n");
numeric **matrix_x;
matrix_x = create_matrix(m, l);
matrix_x = standard_matrix_multiplication(m, n, l);
print_matrix(matrix_x, m, l);
break;
}
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//----------------------------------------------------------MATRIX MULTIPLICATION IMPLEMENTATIONS--------------------------------------------------//
numeric **standard_matrix_multiplication(int m, int n, int l) {
numeric **matrix_a; numeric **matrix_b; numeric **matrix_k;
matrix_a = create_matrix(m, n);
matrix_b = create_matrix(n, l);
matrix_k = create_matrix(m, l);
input_matrix(matrix_a, m, n);
print_matrix(matrix_a, m, n);
input_matrix(matrix_b, n, l);
//print_matrix(matrix_b, n, l);
for(int i = 0; i < m; i++) {
for (int j = 0; j < l; j ++) {
for (int k = 0; k < n; k++) {
matrix_k[i][j] += matrix_a[i][k] * matrix_b[k][j];
}
}
}
return matrix_k;
}
//-------------------------------------------------------------------------------------------------------------------------------------------------//
//---------------------------------------------------------------HELPER FUNCTIONS------------------------------------------------------------------//
numeric **create_matrix(int x, int y) {
numeric **matrix = (numeric**)malloc(x * sizeof(numeric*)); // Dynamically creating an array of pointers
for (int i = 0; i < x; i++) {
matrix[i] = (numeric*)malloc(y * sizeof(numeric)); // Dynamically allocating memory for each columns of the matrix
}
return matrix;
}
void input_matrix(numeric **matrix, int m, int n) {
printf("Enter the elements of the matrix, row wise.\n"); // Instructing the user on matrix entry
printf("For example, to enter the matrix\n");
printf("\t\t1\t2\n");
printf("\t\t3\t4\n");
printf("enter 1, 2, 3, and 4 in that order.\n");
for (int i = 0; i < m; i++) { // Iterating through the rows and columns of the matrix
for (int j = 0; j < n; j++) {
scanf("%Lf", &matrix[i][j]); // Accepting each element
}
}
}
void print_matrix(numeric **l, int x, int y) { // To print a matrix
for (int i = 0; i < x; i++) {
for (int j = 0; j < y; j++) {
printf("%0.10Lf\t", l[i][j]); // Printing numeric type values
}
printf("\n");
}
printf("\n");
}
You are not allocating enough memory for matrix_k. You are allocating memory for m rows and l columns, but you are trying to access m rows and n columns. You need to allocate memory for m rows and n columns. You can do this by changing the line
matrix_k = create_matrix(m, l);
to
matrix_k = create_matrix(m, n);
This is the same problem you had in your other question.
I wrote some code and it showed me this error: Exception thrown at 0x00007FF93F57B016 (ucrtbased.dll) in Ficha 5.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFFFFFFFFF.
I can't find the reason behind it.
#include <stdio.h>
#define num 10
void ler_matriz(int **matriz1, int n, int m);
void mostrar_matriz(int matriz1[num][num], int n, int m);
//int num_min_matriz(int matriz1[][], int n, int m);
//void teste_simetria(int matriz1[][], int n, int m);
//void transposta_matriz(int matriz1[][], int n, int m);
//void soma_matriz(int matriz1[][], int matriz2[][], int matriz3[][], int n, int m);
int main()
{
int x[num][num], y[num][num], z[num][num], numL, numC;
printf("Introduza o número de linhas e colunas para a matriz:\n");
scanf(" %d%d", &numL, &numC);
printf("\n\nIntroduza os valores para a matriz 1: ");
ler_matriz(x, numL, numC);
mostrar_matriz(x, numL, numC);
return 0;
}
void ler_matriz(int **matriz1, int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
printf("\nx[%d][%d]: ", i + 1, j + 1);
scanf(" %d", &matriz1[i][j]); // the exception error
}
}
}
void mostrar_matriz(int matriz1[num][num], int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; i < m; j++)
{
printf("%d ", matriz1[i][j]);
}
putchar('\n');
}
}
You have:
for (int j = 0; i < m; j++)
This should be
for (int j = 0; j < m; j++)
Otherwise, i < m is going to be true forever (because you're not changing i in that loop) and you'll eventually be accessing 0xFFFFFFFFFFFFFFFF (the very edge of memory).
For memory errors like this a good idea is to use a memory checking tool (you can try valgrind memcheck). Now let's see what's wrong with your code :)
The array
You have to take into account that int[m][n] isn't the same as int**. Using the gcc compiler you'll get a warning about it. (Of course, you can alter your code to use int**)
The For Loop
Just as VoteyDisciple said you should be using
for (int j=0;j<m;j++)
instead of
for(int j=0;i<m;j++)
Uninitialized values
Creating an array and not initializing it can lead to memory errors later on (assuming we're talking about C - some languages initialize arrays with 0's). Here you create the x,y,z matrixes but you end up using a portion of them which you assign values to. The rest remain uninitialized and you can end up running into errors if you try accessing them later on.
The scanf exception
Really the exception you get is due to the above, as you're getting errors from trying to access the memory address at &matriz1[i][j]
Fixing it all
Here's how I'd write your code so that it works:
#include <stdio.h>
#include <stdlib.h>
#define num 10
void ler_matriz(int **matriz1, int n, int m);
void mostrar_matriz(int** matriz1, int n, int m);
//int num_min_matriz(int matriz1[][], int n, int m);
//void teste_simetria(int matriz1[][], int n, int m);
//void transposta_matriz(int matriz1[][], int n, int m);
//void soma_matriz(int matriz1[][], int matriz2[][], int matriz3[][], int n, int m);
int main()
{
//int x[num][num], y[num][num], z[num][num], numL, numC;
int i,j,**x,**y,**z,numL,numC; //Proper declarations
x=malloc(num*sizeof(int*));
y=malloc(num*sizeof(int*));
z=malloc(num*sizeof(int*));
for(i=0;i<num;i++) {
x[i]=malloc(num*sizeof(int));
y[i]=malloc(num*sizeof(int));
z[i]=malloc(num*sizeof(int));
}
//Initialization
for(i=0;i<num;i++) {
for(j=0;j<num;j++) {
x[i][j]=y[i][j]=z[i][j]=0;
}
}
printf("Introduza o número de linhas e colunas para a matriz:\n");
scanf(" %d%d", &numL, &numC);
printf("\n\nIntroduza os valores para a matriz 1: ");
ler_matriz(x, numL, numC);
mostrar_matriz(x, numL, numC);
for(i=0;i<num;i++) {
free(x[i]);
free(y[i]);
free(z[i]);
}
free(x);
free(y);
free(z);
return 0;
}
void ler_matriz(int **matriz1, int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
printf("\nx[%d][%d]: ", i + 1, j + 1);
scanf(" %d", &matriz1[i][j]);
}
}
}
void mostrar_matriz(int **matriz1, int n, int m)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
printf("%d ", matriz1[i][j]);
}
putchar('\n');
}
}
I feel like I've attempted every combination I know of to get this to work and can't figure it out. How can I scanf() into an int** passed as a pointer to a function? I tried searching but couldn't find this, if it's a duplicate please let me know and I'll delete. It begins to run and after entering a few values it segfaults.
Here's my code, I think it's messing up on the scanf() line of the setMatrix() function:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int ***mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", mat[i][j]); // problem here??
printf("matrix[%d][%d]: %d\n", i, j, (*mat)[i][j]);
}
}
return;
}
// print matrix
void printMatrix(int ***mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", (*mat)[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(&mat, r, c);
printMatrix(&mat, r, c);
}
There is no need to use triple pointer ***. Passing two-dimensional array will work as is. Here is the code:
#include <stdio.h>
#include <stdlib.h>
// create zero initialized matrix
int** callocMatrix(int rmax, int colmax) {
int **mat = calloc(rmax, sizeof(int*));
for(int i = 0; i < rmax; i++) mat[i] = calloc(colmax, sizeof(int));
return mat;
}
// fill matrix
void setMatrix(int **mat, int r, int c){
printf("Insert the elements of your matrix:\n");
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
printf("Insert element [%d][%d]: ", i, j);
scanf("%d", &mat[i][j]); // no problem here
printf("matrix[%d][%d]: %d\n", i, j, mat[i][j]);
}
}
}
// print matrix
void printMatrix(int **mat, int r, int c){
for (int i=0; i<r;i++){
for (int j=0; j<c;j++) {
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main(int argc, char *argv[]) {
int r = 3, c = 3;
int **mat = callocMatrix(r, c);
setMatrix(mat, r, c);
printMatrix(mat, r, c);
}
Should be:
scanf("%d", &(*mat)[i][j]);
You're passing a pointer to you matrix object, so you need to dereference it (with *) just as you do with printf. scanf then needs the address of the element to write into, so you need the &
I'm new here and this is my first question, i couldn't find anything like this in the search engine so my problem is basically a vector of vectors on C, here is what i have done until now but i keep getting a deadly warning, so i know that I'm not using well the structure with the vector and I'd really appreciate some help.
Thanks
PD: Sorry for my english.
#include<stdio.h>
#include<stdlib.h>
typedef struct
{
int n;
int *vector;
}Vector_T;
int inicializar_original(int *n,int dim)
{
int i,r,s,j,*k;
Vector_T *t;
Vector_T l;
srand(time(NULL));
r=rand()%10;
scanf("%d",&s);
t->vector=k;
l.n=s;
k=(int*)malloc(s*sizeof(int));
for(j=0;j<s;j++)
{
k[j]=r;
}
for(i=0;i<dim;i++)
{
n[i]=k;
}
}
int main()
{
int *v,dim;
scanf("%d",&dim);
v=(int*)malloc(dim*sizeof(int));
inicializar_original(v,dim);
}
Asumo que hablas español, así que aquí va: El problema más grande es que no estás inicializando la variable "k". Mi sugerencia es que intentes lo siguente:
int i,r,s,j;
int* k;
If English only: Your problem is probably that you're initializing K in the wrong way. Try to do:
int i,r,s,j;
int* k;
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct {
int n;
int *vector;
}Vector_T;
int inicializar_original(Vector_T *v, int dim){
int i, j, s, r = rand()%10;
scanf("%d", &s);
for(i=0; i<dim; i++){
int *k = malloc( s * sizeof(int));
for(j=0; j<s; j++){
k[j]=r;
}
v[i].n = s;
v[i].vector = k;
}
}
int main(void){
Vector_T *v;
int dim;
srand(time(NULL));
scanf("%d", &dim);
v = malloc(dim * sizeof(*v));
inicializar_original(v, dim);
{ //check print & release
int i, j;
for(i = 0; i < dim; ++i){
for(j = 0; j < v[i].n ; ++j){
printf("%d ", v[i].vector[j]);
}
puts("");
free(v[i].vector);
}
free(v);
}
return 0;
}
Here is my try. I am not totally sure about my manipulations with the pointer. Maybe this is why I am wrong, maybe there is some other case. I want to take the dimensions from the user and create a square matrix, make some manipulations with its elements, and display the original and results to the user. Last time I accomplished this by creating a 100x100 array, and specifying the end of each line, and end of lines by constants. Then I would print all the elements up to this constant. But it does not seem to be right to create a 100x100 array for 4x4 matrices. I could create a smaller array, but this does not seem to be the right solution to the problem. Is there a way in C to create a 2d array exactly the size specified by the users (it will be a square array). Thanks
#include <stdio.h>
#include <stdlib.h>
double * createMatrix(int dimentions);
void drawMatrix(double * matrix);
int main(void)
{
int n, i, j;
system("cls");
system("color 70");
system("pause");
puts("Enter the matrix's dimension");
scanf("%i", &n);
double * pmatrix = createMatrix(n);
for (i = 0; i < n; ++j)
for (j = 0; j < n; ++j)
{
printf("A%i%i: ", i + 1, j + 1);
scanf("%lf", pmatrix[i][j]);
getchar();
}
for (i = 0; i < n; ++i)
{
putchar('\n');
for (j = 0; j < n; ++j)
printf(" %lf ", &pmatrix[i][j]);
}
system("color 08");
return 0;
}
double * createMatrix(int n)
{
const int N = n;
const int N1 = N;
double matrix[N][N];
double * pmatrix = matrix;
return pmatrix;
}
You can create a matrix directly; you don't need a function for that. Replace the code
double * pmatrix = createMatrix(n);
by the regular way of declaring a 2-D array:
double matrix[n][n];
One more way of doing it using pointers.
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char *argv[])
{
double **pmatrix;
int rowsize, colsize, i, j;
printf("Enter the number of rows: ");
scanf("%d",&rowsize);
printf("Enter the number of columns: ");
scanf("%d",&colsize);
//Allocate memory for 2D array
pmatrix = malloc(rowsize*sizeof(double*));
for(i=0;i<rowsize;i++)
{
pmatrix[i] = malloc(colsize*sizeof(int));
}
//Accepting the values
for(i=0;i<rowsize;i++)
{
for(j=0;j<colsize;j++)
{
printf("A %i %i: ", i + 1, j + 1);
scanf("%lf",&pmatrix[i][j]);
}
}
//Printing the values
for(i=0;i<rowsize;i++)
{
for(j=0;j<colsize;j++)
{
printf("%lf\t",pmatrix[i][j]);
}
printf("\n");
}
//Free the memory
for(i=0;i<rowsize;i++)
free(pmatrix[i]);
free(pmatrix);
return 0;
}