Matrix that makes use of an struct - c

I have a matrix, and a struct with 2 int variables.
struct virus {
int gen;
int neighbours;
}
I want to initialize my full gen matrix with the 1 value. The problem is it doesn't work for the first column of the matrix.
I'll post down bellow the code.
Also when I tried to set my matrix as the virus struct it didn't work and I had to initialize a new matrix that I called b.
It's just a simple initialization and a printing.
#include <stdio.h>
struct virus {
int gen;
int neighbours;
};
void initGen(int n, int a[][100])
{
struct virus b[n][100];
int i,j;
for(i = 0; i < n; i++)
{
for(j = 0; j < n; j++)
{
b[i][j].gen = 1;
}
}
}
void printMatrixGen(int n, int b[][100])
{
struct virus a[n][100];
int i;
for(i = 0; i < n; i++)
{
int j;
for(j = 0; j < n; j++)
printf("%d\t", a[i][j].gen);
printf("\n");
}
}
int main(void)
{
int a[100][100], n;
n = 4;
initGen(n,a);
printMatrixGen(n,a);
return 0;
}
The output is the matrix
0 1 1 1
0 1 1 1
0 1 1 1
0 1 1 1
Instead of
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1

Your code passes a wrong array. You need to change function signatures as follows:
void initGen(int n, struct virus a[][100]);
void printMatrixGen(int n, struct virus a[][100]);
After that, remove local declaration of struct virus b arrays, and use structs passed as parameters.
Finally, declare your struct array inside main, and pass it to both functions:
struct virus a[100][100];
int n = 4;
initGen(n, a);
printMatrixGen(n, a);

Related

Snake sort a 2D array with pointers

I'm bad at C pointers, I'm not sure how should I sort the whole array, the code below sorted the array row-wise only, with a warning "assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]". This code sure works in Windows, not sure for other OSes. I am supposed to create a function called snake with 2D const int pointer array, and its size, m as inputs. I am not allowed to move or swap the contents within the array to be scanned, also the whole main function is not allowed to be edited. For example, the input for the whole program is
3
9 8 7
5 4 6
3 2 1
The correct output should be
1 2 3
6 5 4
7 8 9
Instead, I got this
7 8 9
4 5 6
1 2 3
And here is my code. There is a commented section in snake() because the assert function will fail if I uncomment it. I was trying to reverse the even rows (but the index starts from 0, so you can say odd rows also) after sorting.
#include <stdio.h>
#include <assert.h>
void snake(const int *ptr_array[100][100], int m){
int* p =NULL;
int temp;
for(int y=0;y<m;y++){
for(int k=0;k<m-1;k++){
for(int g=0;g<m-k-1;g++){
if(*ptr_array[y][g]>*ptr_array[y][g+1]){
p=(ptr_array[y][g]);
(ptr_array[y][g])=(ptr_array[y][g+1]);
(ptr_array[y][g+1]) = p;
}
}
}
}
// for(int h=1;h<m;h+=2){
// for(int g=0;g<m/2;g++){
// p = (ptr_array[h][m-g]);
// (ptr_array[h][m-g]) = (ptr_array[h][g]);
// (ptr_array[h][g]) = p;
// }
// }
}
int main()
{
int array[100][100], check[100][100];
const int *ptr_array[100][100];
int i, j, m;
scanf("%d", &m);
for (i = 0; i < m; i++){
for (j = 0; j < m; j++) {
ptr_array[i][j] = &(array[i][j]);
scanf("%d", &(array[i][j]));
check[i][j] = array[i][j];
}
}
snake(ptr_array, m);
for (i = 0; i < m; i++) {
for (j = 0; j < m; j++) {
assert(check[i][j] == array[i][j]);
assert((ptr_array[i][j] >= &array[0][0]) && (ptr_array[i][j] <= &array[99][99]));
printf("%d ", *(ptr_array[i][j]));
}
printf("\n");
}
return 0;
}
#include <stdio.h>
void snake(const int *ptr_array[100][100], int m){
int* p =NULL;
int* w=NULL;
int temp,l;
for(int y=0;y<m;y++){
for(int k=0;k<m;k++){
p = ptr_array[y][k];
l = k+1;
for(int g=y;g<m;g++){
while(l<m){
if(*p>*ptr_array[g][l]){
p=(ptr_array[g][l]);
(ptr_array[g][l])=(ptr_array[y][k]);
(ptr_array[y][k]) = p;
}
l++;
}
l=0;
}
}
}
for(int h=1;h<m;h+=2){
for(int g=0;g<=(m-1)/2;g++){
w = (ptr_array[h][m-1-g]);
(ptr_array[h][m-1-g]) = (ptr_array[h][g]);
(ptr_array[h][g]) = w;
}
}
}

Display struct variable with printf("\n")

I tried implemented matrix struct in C, ( generate and show that ). I don't have a trouble with generate but i discovered something I didn't understand. When i uncomment printf("\n") i don't get variable from matrix but whith commented printf("\n") everything working correct. It's not a big problem but I'm curious why this happen. It's looks like printf has destructed my structure.
void show_matrix(struct matrix matrix1){
for(int i =0; i < matrix1.number_of_row; i++){
for(int j = 0; j <matrix1.number_of_columns; j++){
printf("%d " , matrix1.variable[i * matrix1.number_of_columns + j]);
}
// printf("\n");
}
}
Here is my main :
#include <stdio.h>
#include "matrix_operations.h"
int main(){
int columns;
int rows;
printf("Enter the number of columns \n");
scanf("%d",&columns);
printf("Enter the number of rows \n");
scanf("%d", &rows);
struct matrix matrix1;
matrix1 = generate_matrix(columns,rows);
show_matrix(matrix1);
return 0;
}
Here is my file matrix_operations.h :
#include "matrix.h"
#include <stdlib.h>
struct matrix generate_matrix(int columns, int rows){
int value;
struct matrix matrix1;
matrix1.number_of_columns = columns;
matrix1.number_of_row = rows;
int values[rows * columns];
matrix1.variable = values;
for(int i = 0 ; i < rows ; i++){
for(int j =0 ; j <columns ; j++){
value = random() %2;
matrix1.variable[i * columns +j] = value;
/* Uncomment to see generated matrix
printf("%d ", matrix1.values[ i * columns +j]);
*/
}
/* Uncomment to see generated matrix
printf("\n");
*/
}
return matrix1;
}
void show_matrix(struct matrix matrix1){
for(int i =0; i < matrix1.number_of_row; i++){
for(int j = 0; j <matrix1.number_of_columns; j++){
printf("%d " , matrix1.variable[i * matrix1.number_of_columns + j]);
}
/* Uncomment to not working correctly
printf("\n");
*/
}
}
Here is my struct in file matrix.h :
struct matrix{
int number_of_columns;
int number_of_row;
int *variable;
};
Sample input :
4
4
Sample output with commented printf (16 random numbers 0 or 1):
1 0 1 1 0 0 1 1 0 0 1 1 0 1 0 1
Sample output with uncommented printf
1 0 1 1
-2051332800 32571 0 0
0 0 -2053095405 32571
-2051684704 32571 10 0
The problem is that generate_matrix returns a struct matrix with a variable field that points at a local variable (values) of the function. This goes out of scope when the function returns, leaving you with a dangling pointer, and when you later dereference it, you get undefined behavior.
You need to ensure that this pointer points at something with sufficient lifetime to not become dangling. One way to do that would be to use malloc in the generate_matrix function rather than using a local variable:
int *values = malloc(rows * columns * sizeof(int));
This will allocate memory that lasts until you explicitly free it. Now you have the issue that you need to figure out when to free it (when you no longer need it), or you'll have a memory leak.

I can't use an existent variable inside a for loop

This code should make a sum of the numbers in the main diagonal of a matrix.
#include <stdio.h>
#define RIG 2
#define COL 5
void sum(unsigned int a[RIG][COL]);
int main(){
unsigned int a[RIG][COL] = {{1,2,3,4,5},{6,7,8,9,10}};
sum(a);
}
void sum(unsigned int a[RIG][COL]){
unsigned int c = 0;
unsigned int j = 0;
if (RIG<=COL){
int n = RIG;
}
else{
int n = COL;
}
for (size_t i=0;i<=n-1;++i){
c += a[i][j];
j += 1;
}
printf("%d\n", c);
}
Output:
matrix_sum.c:28:21: error: use of undeclared identifier 'n'
for (size_t i=0;i<=n-1;++i){
^
1 error generated.
I don't get why I can't use the n variable inside the for loop. How can I do that?
This
if (RIG<=COL){
int n = RIG;
}
else{
int n = COL;
}
does not scope n the way you might think it does. Scoping rules are better explained here, but in short: n exists only within each branch of the if/else block. As such, when you attempt to access n in your for-loop later on, it no longer exists!
This is trivially remedied by bringing n into scope, e.g.
int n = COL;
if (RIG <= COL) {
n = RIG;
}
for (size_t i = 0; i <= n - 1; ++i) {
c += a[i][j];
j += 1;
}

C: Overwrite Array2D values not working when using function

I want max to have the content of tmp_max. max is dynamically allocated. tmp_max size is known.
Copying the values is working correctly when I hardcode it but it doesn't work when I create a function to copy the values. Why is that?
//This code works
int** max;
init2D(&max,3,4);
int tmp_max[3][4] = {{3,3,2,2}, {1,2,3,4}, {1,3,5,0}};
for(int i = 0 ; i < 3; i++)
for(int j = 0 ; j < 4; j++)
max[i][j] = tmp_max[i][j];
assert(max[0][1] == 3);
//This one crashes
void copyArray2D(int a, int b, int*** tab,int*** tab2){
for(int i = 0 ; i < a; i++)
for(int j = 0 ; j < b; j++)
tab2[i][j] = tab[i][j];
}
int** max;
init2D(&max,3,4);
int tmp_max[3][4] = {{3,3,2,2}, {1,2,3,4}, {1,3,5,0}};
copyArray2D(3,4,&tmp_max,&max); //crash
assert(max[0][1] == 3);
Note:
Using void copyArray2D(int a, int b, int** tab,int** tab2){and copyArray2D(3,4,max,tmp_max); isn't working either.
Using void copyArray2D(int a, int b, int** tab,int** tab2){and copyArray2D(3,4,&max,&tmp_max); isn't working either.
void init2D(int ***data_ptr, int x, int y) {
int **data = (int **) malloc(sizeof(int *) * x);
for (int k = 0; k < x; k++)
data[k] = (int *) malloc(sizeof(int) * y);
*data_ptr = data;
}
Your compiler should complain about copyArray2D(3,4,&tmp_max,&max).
You must fix any issues identified by your compiler before trying to run your code (running any such executable based on broken code is meaningless).
One problem is that copyArray2D says int*** when it should say int**.
After fixing that, the main issue here is that you have written copyArray2D so that it only works with an array of pointers. (You are simulating a 2-D array by allocating an array of pointers, and then making each pointer point to a separate allocation representing each row).
This works when you use init2D because the init2D function allocates an array of pointers etc.
However int tmp_max[3][4] is a block of 12 contiguous ints. There are no pointers. This is not compatible with copyArray2D.
Your options are:
Use int **tmp_max and use init2D to allocate it, instead of int tmp_max[3][4]
Make another version of copyArray2D which works on a contiguous 2-D array.
Use an ugly macro
Your second function has too many stars. You hadn't shown the init2D function when I first wrote an answer, so I had to guess what you'd done with that (but the code is now in the question and is close enough to what I produced that the difference is immaterial — except I do error check the allocations). Here's a (rewritten) version of the code (the first version hadn't been near a compiler, and I completely missed a crucial detail). Note that int ** is not the same as int arr[N][M] or variations on the theme — even if you use the same notation to access both.
#include <stdio.h>
#include <stdlib.h>
static void copyArray2D(int a, int b, int **dst, int src[a][b])
{
for (int i = 0; i < a; i++)
for (int j = 0; j < b; j++)
dst[i][j] = src[i][j];
}
static void oom(void)
{
fprintf(stderr, "Out of memory\n");
exit(1);
}
static void init2D(int ***arr, int a, int b)
{
(*arr) = malloc(a * sizeof((*arr)[0]));
if (*arr == 0)
oom();
for (int i = 0; i < a; i++)
{
(*arr)[i] = malloc(b * sizeof((*arr)[0][0]));
if ((*arr)[i] == 0)
oom();
}
}
static void dump_2d_array(int a, int b, int arr[a][b])
{
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
printf(" %2d", arr[i][j]);
putchar('\n');
}
}
static void dump_2d_pointers(int a, int b, int **arr)
{
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
printf(" %2d", arr[i][j]);
putchar('\n');
}
}
int main(void)
{
int **max;
init2D(&max, 3, 4);
int tmp_max[3][4] = { { 3, 3, 2, 2 }, { 1, 2, 3, 4 }, { 1, 3, 5, 0 } };
copyArray2D(3, 4, max, tmp_max);
printf("2D array:\n");
dump_2d_array(3, 4, tmp_max);
printf("List of pointers:\n");
dump_2d_pointers(3, 4, max);
return 0;
}
Output from running that code:
2D array:
3 3 2 2
1 2 3 4
1 3 5 0
List of pointers:
3 3 2 2
1 2 3 4
1 3 5 0
Note that I've not written a free function, so the memory is leaked.
Be wary of 3-Star Programming.
void copyArray2D(int a, int b, int tab[a][b],int*** tab2){
for(int i = 0 ; i < a; i++)
for(int j = 0 ; j < b; j++)
(*tab2)[i][j] = tab[i][j];
}
copyArray2D(3,4,tmp_max,&max);

Sorting array algorithm error

Hi I wrote this sorting algorithm and I'm not sure why I'm getting the following error: "member reference base type 'int' is not a structure or union"
void sort(float avg_dist, cg[]){
int i,j,t;
for(i=1; i<=cg[i]-1; i++)
for(j=1; j<=cg[i]-i; j++)
if(cg[j-1].avg_dist >= cg[j].avg_dist){
t = cg[j-1];
cg[j-1] = cg[j];
cg[j] = t;
}
}
cg is an int array.
You can't access a "member" of an int, as in
cg[j-1].avg_dist
I'm not sure what you're trying to do. Maybe multiply ?
cg[j-1] * avg_dist
It's not the problem, but you're (perhaps intentionally) omitting the type specifier in your function
void sort(float avg_dist, cg[]){
C is defaulting to an int array type, which of course, renders cg[j].avg_dist syntactically invalid. (In reality you probably want to multiply by avg_dist, use * rather than the member selection operator .).
This should give you a clear Idea:
#include <stdio.h>
void sortArray(int *array, int length){
int i,j, k, temp;
for (i = 0 ; i < length-1; i++){
for (k = 0 ; k < length-i-1; k++){
if (array[k] > array[k+1]){
temp = array[k];
array[k] = array[k+1];
array[k+1] = temp;
}
}
}
printf("The result:\n");
for ( j = 0 ; j < length ; j++ ){
printf("%d ", array[j]);
}
}
int main(void){
int array[] = {1,4,2,-1,2,3,4,1,3,-1};
int length = sizeof array / sizeof array[0];
sortArray(array, length);
printf("\n");
return 0;
}
Output:
The result:
-1 -1 1 1 2 2 3 3 4 4

Resources