I would like to make an array of structure with dynamic allocation of memory for the structure and the two matrix
typedef struct {
int **cont;
double **doubmat;
} libra;
int main(int argc, char *argv[]) {
libra *arra = calloc(Nfr,sizeof(libra));
for (i = 0; i < Nfr; i++) {
arra[i].doubmat = calloc(Nmol, sizeof (libra));
}
for (i = 0; i < Nfr; i++) {
for (j = 0; j < Nmol; j++) arra[i].doubmat[j] = calloc(Nmol, sizeof (libra));
}
for (i = 0; i < Nfr; i++) {
arra[i].cont = calloc(Nmol, sizeof (libra));
}
for (i = 0; i < Nfr; i++) {
for (j = 0; j < Nmol; j++) arra[i].cont[j] = calloc(Nmol, sizeof (libra));
}
}
but i have some trouble with memory, the numbers during the calculation depends on the number of structure in the array. I think that I'm making some mistake with the allocation.
Anyone have some tips ?
Thanks in advance for your help.
You have specified incorrect sizeof(type) to allocate memory for matrices.
You need to do something like that:
typedef struct {
int **cont;
double **doubmat;
} libra;
int main(int argc, char *argv[]) {
libra *arra = calloc(Nframe,sizeof(libra));
for (i = 0; i < Nfr; i++) {
arra[i].doubmat = calloc(Nmol, sizeof(*arra[i].doubmat));
for (j = 0; j < Nmol; j++)
arra[i].doubmat[j] = calloc(Nmol, sizeof(**arra[i].doubmat));
}
for (i = 0; i < Nfr; i++) {
arra[i].cont = calloc(Nmol, sizeof(*arra[i].cont));
for (j = 0; j < Nmol; j++)
arra[i].cont[j] = calloc(Nmol, sizeof(**arra[i].cont));
}
}
Supposing that NFrame is declared, I am going to show the allocation for an array of consisting of Nframe structs, each of which contains a NrowsxNcols doubmat:
typedef struct {
int **cont;
double **doubmat;
} libra;
int main(int argc, char *argv[]) {
int i, j, Nrows = ..., Ncols = ...;
libra *arra = calloc(Nframe, sizeof(libra));
for (i = 0; i < Nframe; i++) {
arra[i].doubmat = calloc(Nrows, sizeof(double*));
if (arra[i].doubmat == NULL)
return;
for (j = 0; j < Nmol; j++){
arra[i].doubmat[j] = calloc(Ncols, sizeof(double));
if (arra[i].doubmat[j] == NULL)
return;
}
}
}
Related
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.
I need to read a file which contain numbers, and make 4 rows and 5 columns matrices from those numbers. Then, I need to add these matrices and print the sum matrix (the numbers of matrices depends on the user input).
#include <stdio.h>
#include <stdlib.h>
void main(int argc, char *argv[]) {
int a = 4;
int b = 5;
int m;
scanf("%d", &m);
FILE *file = fopen("matrix.txt", "r");
int arr[a][b][m], i, j, k;
for (i = 0; i < a; i++) {
for (j = 0; j < b; j++) {
for (m = 0; k < m; k++) {
fscanf(file, "%d", &arr[i][j][k]);
arr[i][j] += arr[i][j];
}
}
}
for (i = 0; i < a;i++) {
for (j = 0; j < b; j++) {
for (k = 0; k < m; k++) {
printf("%d", arr[i][j][k]);
printf("\t");
}
printf("\n");
}
}
}
You don't need to load the matrix data into separate matrices, you can just add the matrix contents on the fly as you read each matrix from the file:
#include <errno.h>
#include <stdio.h>
#include <string.h>
void main(int argc, char *argv[]) {
int m;
if (scanf("%d", &m) != 1)
return 1;
const char *filename = "matrix.txt";
FILE *file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno));
return 1;
]
int a = 4;
int b = 5;
int sum[a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
sum[i][j] = 0;
}
}
for (int k = 0; k < m; k++) {
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
int value;
if (fscanf(file, "%d", &value) != 1) {
fprintf(stderr, "not enough data\n");
return 1;
}
sum[i][j] += value;
}
}
}
fclose(file);
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
printf("%d\t", sum[i][j]);
}
printf("\n");
}
return 0;
}
If you are required to load all the data in memory, use an array of matrices: int arr[m][a][b]; and 2 separate loops to read and sum the data:
#include <errno.h>
#include <stdio.h>
#include <string.h>
void main(int argc, char *argv[]) {
int m;
if (scanf("%d", &m) != 1)
return 1;
const char *filename = "matrix.txt";
FILE *file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "cannot open %s: %s\n", filename, strerror(errno));
return 1;
]
int a = 4;
int b = 5;
int arr[m][a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
sum[i][j] = 0;
}
}
for (int k = 0; k < m; k++) {
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
if (fscanf(file, "%d", &arr[k][i][j]) != 1) {
fprintf(stderr, "not enough data\n");
return 1;
}
}
}
}
fclose(file);
int sum[a][b];
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
int s = 0;
for (int k = 0; k < m; k++) {
s += arr[k][i][j];
}
sum[i][j] = s;
}
}
for (int i = 0; i < a; i++) {
for (int j = 0; j < b; j++) {
printf("%d\t", sum[i][j]);
}
printf("\n");
}
return 0;
}
I know that object oriented is not welcoming in c language but I still trying to work my way because it is possible as later languages based on c works good with objects
so my question is when I try to write a function outside of main it doesnt give me access and doesnt change values of wanted structs , see code below (I marked every things and included working functions inside the main) :
#include <stdio.h>
#include <stdlib.h>
static int RandomNum() {
int generate = rand() / 100000000;
while (generate >= 9) {
generate = rand() / 100000000;
}
return generate;
}
// Object Definition
typedef struct {
int a, b;
int Mat[2][4];
} Matrix2x4;
typedef struct {
int a, b;
int Mat[4][5];
} Matrix4x5;
typedef struct {
int a, b;
int Mat[4][5];
} Matrix2x5;
void PrintMat2x4(Matrix2x4 a) {
int row = a.a;
int col = a.b;
for (int i = 0; i < row; i++) {
printf("{%s", " ");
for (int j = 0; j < col; j++) {
printf("%d ,", a.Mat[i][j]);
}
printf("}%s\n", " ");
}
}
void PrintMat4x5(Matrix4x5 a) {
int row = a.a;
int col = a.b;
for (int i = 0; i < row; i++) {
printf("{%s", " ");
for (int j = 0; j < col; j++) {
printf("%d ,", a.Mat[i][j]);
}
printf("}%s\n", " ");
}
}
void PrintMat2x5(Matrix2x5 a) {
int row = a.a;
int col = a.b;
for (int i = 0; i < row; i++) {
printf("{%s", " ");
for (int j = 0; j < col; j++) {
printf("%d ,", a.Mat[i][j]);
}
printf("}%s\n", " ");
}
}
// NOT WORKING AS A SEPERATE FUNCTION SO I PUT IT INSIDE THE MAIN
/*static void MatrixMultiplication (Matrix2x4 a , Matrix4x5 b , Matrix2x5 c) {
for (int i = 0; i < a.b; i++){
for (int j = 0; j < b.b; j++){
for (int k = 0; k < a.b; k++){
c.Mat[i][j] = c.Mat[i][j]+(a.Mat[i][k]*b.Mat[k][j]);}}}
}
void setRandom (Matrix a) {
int row = ((int)(sizeof (a.Mat) / sizeof (a.Mat)[0])) ;
int col = ((int)(sizeof (a.Mat)[0] / sizeof (a.Mat)[0][0])) ;
for (int i = 0; i < row ; i++){
for (int j = 0; j < col; j++){
a.Mat[i][j] = RandomNum();}}}*/
void main() {
printf("%s\n\n", "Start..");
Matrix2x4 test = {2,4,{0}}; // <----- SIZE IS 2X4
int row = ((int)(sizeof(test.Mat) / sizeof(test.Mat)[0]));
int col = ((int)(sizeof(test.Mat)[0] / sizeof(test.Mat)[0][0]));
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
test.Mat[i][j] = RandomNum();
}
}
Matrix4x5 test2 = {4,5,{0}}; // <----- SIZE IS 4X5
int row2 = ((int)(sizeof(test2.Mat) / sizeof(test2.Mat)[0]));
int col2 = ((int)(sizeof(test2.Mat)[0] / sizeof(test2.Mat)[0][0]));
for (int i = 0; i < row2; i++) {
for (int j = 0; j < col2; j++) {
test2.Mat[i][j] = RandomNum();
}
}
Matrix2x5 mult = {2,5,{0}}; // <----- SIZE IS 2X5
PrintMat2x4(test);
printf("X\n");
PrintMat4x5(test2);
printf("=\n");
for (int i = 0; i < test.b; i++) {
for (int j = 0; j < test2.b; j++) {
for (int k = 0; k < test.b; k++) {
mult.Mat[i][j] = mult.Mat[i][j] + (test.Mat[i][k] * test2.Mat[k][j]);
}
}
}
PrintMat2x5(mult);
printf("\n\n%s", "End ---> ");
}
In order for this function to work:
static void MatrixMultiplication (Matrix2x4 a , Matrix4x5 b , Matrix2x5 c) {
for (int i = 0; i < a.b; i++){
for (int j = 0; j < b.b; j++){
for (int k = 0; k < a.b; k++){
c.Mat[i][j] = c.Mat[i][j]+(a.Mat[i][k]*b.Mat[k][j]);}}}
}
You must pass your structs as pointers:
static void MatrixMultiplication (Matrix2x4* a , Matrix4x5* b , Matrix2x5* c) {
for (int i = 0; i < a->b; i++){
for (int j = 0; j < b->b; j++){
for (int k = 0; k < a->b; k++){
c->Mat[i][j] = c->Mat[i][j]+(a->Mat[i][k]*b->Mat[k][j]);}}}
}
Your original function doesn't work outside of main, because C is making a copy of those structs for the function's own use. Therefore the original structs never get modified. Changing those parameters to pointers means that the function is working with the original structs.
I think this is C. but trying to figure out why my bubble sort isn't working. I was following an existing example so perhaps my integration with this code isn't right but not too sure.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
printf("%s <student-id>\n", argv[0]);
exit(0);
}
int i;
int size = 10000;
int seed = atoi(argv[1]);
srand(seed % 4);
int *int_array = malloc(sizeof(int)*size);
for (i = 0; i < size; i++)
{
int_array[i] = rand();
}
// This part
int j;
for (i = 0; i < size; i += 1) {
for (j = i - 1; j >= 0 && int_array[j] > int_array[j + 1]; j+= 1) {
swap(int_array,j);
}
}
int failed = 0;
for (i = 0; i < size; i++)
{
if (int_array[i] < int_array[i+1])
{
failed = 1;
break;
}
}
free(int_array);
return 0;
}
This is my code for bubble sort:
for (int i = 0; i < size; i += 1)
{
for (j = i + 1; j < size; j+= 1)
{
//this for starts from i+1 because I want to compare element int_array[i] whith the rest of the array. Each time this for starts, int_array is sorted from 0 to i-1
if(int_array[i] > int_array[j]) swap(int_array[i], int_array[j]);
}
}
int ** ARR;
int LENGTH = 1;
int DEPTH = 1;
void loadt(int ** terr)
{
terr = (int**)malloc(sizeof(int*) * (LENGTH + 1));
int i, j;
for(i = 1; i <= LENGTH; i++)
terr[i] = (int*)malloc(sizeof(int) * (DEPTH + 1));
for(i = 1; i <= LENGTH; i++)
for(j = 1; j <= DEPTH; j++)
scanf("%d", &terr[i][j]);
}
void freet(int ** terr)
{
int i;
for(i = 1; i <= LENGTH; i++){
free(terr[i]);
}
free(terr);
}
int main(int argc, char* argv[])
{
loadt(ARR);
freet(ARR);
return 0;
}
Hello. I probably miss sth really basic here but after I run the program it crashes."Segmentation fault (core dumped)" Why?
Because in c arguments to functions are always passed by value, so your unecessarily global variable is not getting reassigned inside the function since you are passing it as a parameter and hence a copy of it is made, which is the one that is actually reassigned.
So you are calling free() on an uninitialized poitner.
Try like this
int **loadt(int LENGTH, int DEPTH)
{
int **terr;
int i, j;
terr = malloc(sizeof(int*) * (LENGTH + 1));
if (terr == NULL)
return NULL;
for (i = 1; i <= LENGTH; i++) {
terr[i] = malloc(sizeof(int) * (DEPTH + 1));
if (terr[i] == NULL) {
for (j = i ; j >= 0 ; --j) {
free(terr[j]);
}
free(terr);
return NULL;
}
}
for (i = 1; i <= LENGTH; i++) {
for (j = 1; j <= DEPTH; j++) {
scanf("%d", &terr[i][j]);
}
}
return terr;
}
void freet(int **terr)
{
int i;
if (terr == NULL)
return; // `free()' also accepts NULL pointers
for (i = 1; i <= LENGTH; i++) {
free(terr[i]);
}
free(terr);
}
int main(int argc, char* argv[])
{
int **ARR;
int LENGTH = 1;
int DEPTH = 1;
ARR = loadt(LENGTH, DEPTH);
freet(ARR);
return 0;
}
Another problem, is that you start your loops at i = 1, which is fine because you are allocating enough space, but it's not the way you should do it. Instead for (i = 0 ; i < LENGTH ; ++i) would be how a c programmer would do it. Note that you are wasting the first element of your array.