-1

can you help me to find a way for my program? In this programm i need to find min values of my matrix, and compare them and then find the biggest of min values. I did it with pointers< is there one more variant to find a min value without pointers and struct?I think, i can use global variables, if im right, can you support me? Thanks... here is my code with pointers...

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <time.h>

int ch_data(const int,const int,const int,const int);
int** my_array(const int,const int);
void numbers_for_my_array(int** const,const int,const int);
void print_my_array(int** const,const int, const int);
void min_my_array(int** const ,const int ,const int, int*, int*, int*);
int my_mod(int);
int comp_my_array (int,int,int);



int main()
{
    int N,M,L,K,**a=NULL,**b=NULL,**c=NULL,B;

    printf("%s",read);
    while (1){
    printf("Enter N: ");
    scanf("%d",&N);
    printf("Enter M: ");
    scanf("%d",&M);
    printf("Enter L: ");
    scanf("%d",&L);
    printf("Enter K: ");
    scanf("%d",&K);
    printf("\n\n");

        if (ch_data(N,M,L,K)){
        break;
        }
    }


    int* min_i_a_p, *min_j_a_p, *min_value_a_p;
    int* min_i_b_p, *min_j_b_p, *min_value_b_p;
    int* min_i_c_p, *min_j_c_p, *min_value_c_p;

    int min_i_a = 0, min_j_a = 0, min_value_a = 0;
    int min_i_b = 0, min_j_b = 0, min_value_b = 0;
    int min_i_c = 0, min_j_c = 0, min_value_c = 0;

    min_i_a_p = &min_i_a;
    min_j_a_p = &min_j_a;
    min_i_b_p = &min_i_b;
    min_j_b_p = &min_j_b;
    min_i_c_p = &min_i_c;
    min_j_c_p = &min_j_c;

    min_value_a_p = &min_value_a;
    min_value_b_p = &min_value_b;
    min_value_c_p = &min_value_c;


    a=my_array(N,M);
    numbers_for_my_array(a,N,M);
    print_my_array(a,N,M);
    min_my_array(a, N, M, min_i_a_p, min_j_a_p, min_value_a_p);

    b=my_array(M,L);
    numbers_for_my_array(b,M,L);
    print_my_array(b,M,L);
    min_my_array(b, M, L, min_i_b_p, min_j_b_p, min_value_b_p);

    c=my_array(L,K);
    numbers_for_my_array(c,L,K);
    print_my_array(c,L,K);
    min_my_array(b, M, L, min_i_c_p, min_j_c_p, min_value_c_p);

    printf("min of a[%d][%d]- %d \n", *min_i_a_p, *min_j_a_p, *min_value_a_p);
    printf("min of b[%d][%d]- %d \n", *min_i_b_p, *min_j_b_p, *min_value_b_p);
    printf("min of c[%d][%d]- %d \n", *min_i_c_p, *min_j_c_p, *min_value_c_p);

     B=comp_my_array(*min_value_a_p, *min_value_b_p,*min_value_c_p);

    printf("B = %d",B);



    return 0;
}

int ch_data(int N,int M, int L,int K){
    if((N*M<=300)&&(M*L<=300)&&(K*L<=300)){
        return 1;
    }
    else return 0;
}

int** my_array(const int x, const int y){
    int **array=NULL,i;
    if(!(array=(int**)malloc(x*sizeof(int*)))){
        printf("Error memory");
        exit(0);
        }
    for(i=0;i<x;i++){
        if(!(*(array+i)=(int*)malloc(y*sizeof(int)))){
            printf("Error memory");
            exit(0);
        }
    }
return array;
}

void numbers_for_my_array( int** const a ,const int x,const int y){
    srand(time(NULL));
    int i,j;
    for (i=0;i<x;i++){
        for(j=0;j<y;j++){
            a[i][j]=rand()%100;
        }
    }

}

void print_my_array (int** const array, const int x, const int y)
{
    int i, j;
    for(i=0;i<x;i++)
    {
        for(j=0;j<y;j++)
        {
            printf("%d ", array[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

void min_my_array (int** const a,const int N,const int M, int* min_i, int* min_j, int* min_value)
{
    int i, j,min_a;
    min_a=a[0][0];
    *min_value = min_a;
    for(i=0;i<N;i++)
    {
        for(j=0;j<M;j++)
        {
            if (my_mod(a[i][j])<min_a)
            {
                min_a = my_mod(a[i][j]);
                *min_value = a[i][j];
                *min_i = i;
                *min_j = j;
                *min_value=min_a;
            }
        }
    }
}

int comp_my_array (int min_value_a,int min_value_b,int min_value_c){

    int s1,s2,s3;
    s1=min_value_a;
    s2=min_value_b;
    s3=min_value_c;
    return (s1> s2)? ((s1>s3)? s1 : s3) : ((s2 > s3)? s2 : s3);
}

int my_mod(int x){
    return (x>=0)? x:-x;}
Joshua
  • 40,822
  • 8
  • 72
  • 132
Nikita Gusev
  • 143
  • 10
  • 1
    1) `int **` is not a matrix (aka 2D array), nor can it point to one. A pointer is not an array! 2) You cannot work with array without using pointers. 3) Not clear what your **specific** problem is. We ar not a tutoring service. – too honest for this site Dec 15 '16 at 15:06

1 Answers1

1

First, your program does not compile. This is easy to fix, and is probably the result of a typo. At the beginning of main() you have:

printf("%s", read);

But read is undefined, and I have no idea what you want to print here. Removing this statement (or defining read) solves this problem.

Next, when I tried this code with 3X3 "arrays", they all three had the same elements! This is because you have placed the call to srand() inside the numbers_for_my_array() function. This function is called three times in rapid succession, so that rand() is seeded with the same value each time. The value returned by time() has not changed in this short interval. You only need to call srand() once, and you should probably do it at the beginning of main().

There is an error in your processing of the third "array" c. You need to change:

min_my_array(b, M, L, min_i_c_p, min_j_c_p, min_value_c_p);

to:

min_my_array(c, L, K, min_i_c_p, min_j_c_p, min_value_c_p);

You have memory leaks because you don't free any memory allocations at the end of the program. The rule is, one free for each call to malloc():

/* Free allocated memory */
for (int i = 0; i < N; i++) {
    free(a[i]);
}
free(a);

for (int i = 0; i < M; i++) {
    free(b[i]);
}
free(b);

for (int i = 0; i < L; i++) {
    free(c[i]);
}
free(c);

You could wrap this functionality up in a little function to free the memory allocated for each "array".

You should consider using size_t for the array dimensions and indices. It is an unsigned integer type guaranteed to hold any array index value.

Now, what you have created with dynamic allocation are not arrays, but simulated arrays. This technique is error-prone, and you can easily end up with memory leaks (as you did). You should be using variable length arrays for this (VLAs). These are easy to work with, and since they have automatic storage duration, do not require deallocation.

To convert your code to use VLAs, the my_array() function can be removed, and these function signatures should be changed:

void numbers_for_my_array(const int rows, const int cols, int arr[rows][cols]);
void print_my_array(const int rows, const int cols, int arr[rows][cols]);
void min_my_array(const int rows, const int cols, int arr[rows][cols], int *min_i, int *min_j, int *min_val);

Functions that use VLAs require that the variables that specify the VLA dimensions be declared before the occurrence of the VLA itself in the arguments of the function prototype.

You would then use these VLAs in functions like this:

int a[N][M];
numbers_for_my_array(N, M, a);
print_my_array(N, M, a);
min_my_array(N, M, a, min_i_a_p, min_j_a_p, min_value_a_p);

There is one tricky aspect of converting your code to VLAs: the dynamic arrays that you have are made from pointers to const values, so 2D arrays of const int seem like a reasonable choice. Of course, the numbers_for_my_array() function changes the arrays, but print_my_array() and min_my_array() do not. It would be nice to declare const int arr[rows][cols] in these function prototypes. The tricky part is that, these arrays decay to pointers in the function call, and while C will convert a 1D array of ints to an array of const ints (in that the array decays to a pointer to int, which is converted to a pointer to const int), it will emit warnings when converting a 2D array of ints to a 2D array of const ints. Here is a link that discusses the issue in more detail.. The code still compiles, but to get rid of the warnings you need to do an ugly cast to explicitly cast the type to what the function is expecting:

print_my_array(N, M, (const int (*)[M]) a);
min_my_array(N, M, (const int (*)[M]) a, min_i_a_p, min_j_a_p, min_value_a_p);

Or you can just drop the const qualifiers altogether, if this is too ugly for you.

This should allow you to simplify your code a bit, and no more memory allocation troubles! As a side note, it is a good idea, especially with a function that takes several arguments, to use variable names in the function prototype to document the use of the function.

Here is your program modified to use VLAs; this version does use arrays of const int in the print_my_array() and min_my_array() functions:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int ch_data(const int,const int,const int,const int);
void numbers_for_my_array(const int rows, const int cols, int arr[rows][cols]);
void print_my_array(const int rows, const int cols, const int arr[rows][cols]);
void min_my_array(const int rows, const int cols, const int arr[rows][cols], int *min_i, int *min_j, int *min_val);
int my_mod(int);
int comp_my_array (int,int,int);



int main()
{
    int N, M, L, K, B;

    srand(time(NULL));              // moved from numbers_for_my_array()

    while (1){
        printf("Enter N: ");
        scanf("%d",&N);
        printf("Enter M: ");
        scanf("%d",&M);
        printf("Enter L: ");
        scanf("%d",&L);
        printf("Enter K: ");
        scanf("%d",&K);
        printf("\n\n");

        if (ch_data(N,M,L,K)){
            break;
        }
    }


    int* min_i_a_p, *min_j_a_p, *min_value_a_p;
    int* min_i_b_p, *min_j_b_p, *min_value_b_p;
    int* min_i_c_p, *min_j_c_p, *min_value_c_p;

    int min_i_a = 0, min_j_a = 0, min_value_a = 0;
    int min_i_b = 0, min_j_b = 0, min_value_b = 0;
    int min_i_c = 0, min_j_c = 0, min_value_c = 0;

    min_i_a_p = &min_i_a;
    min_j_a_p = &min_j_a;
    min_i_b_p = &min_i_b;
    min_j_b_p = &min_j_b;
    min_i_c_p = &min_i_c;
    min_j_c_p = &min_j_c;

    min_value_a_p = &min_value_a;
    min_value_b_p = &min_value_b;
    min_value_c_p = &min_value_c;

    int a[N][M];
    numbers_for_my_array(N, M, a);
    print_my_array(N, M, (const int (*)[M]) a);
    min_my_array(N, M, (const int (*)[M]) a, min_i_a_p, min_j_a_p, min_value_a_p);

    int b[M][L];
    numbers_for_my_array(M, L, b);
    print_my_array(M, L, (const int (*)[L]) b);
    min_my_array(M, L, (const int (*)[L]) b, min_i_b_p, min_j_b_p, min_value_b_p);

    int c[L][K];
    numbers_for_my_array(L, K, c);
    print_my_array(L, K, (const int (*)[K]) c);
    min_my_array(L, K, (const int (*)[K]) c, min_i_c_p, min_j_c_p, min_value_c_p);

    printf("min of a[%d][%d]- %d \n", *min_i_a_p, *min_j_a_p, *min_value_a_p);
    printf("min of b[%d][%d]- %d \n", *min_i_b_p, *min_j_b_p, *min_value_b_p);
    printf("min of c[%d][%d]- %d \n", *min_i_c_p, *min_j_c_p, *min_value_c_p);

    B=comp_my_array(*min_value_a_p, *min_value_b_p,*min_value_c_p);

    printf("B = %d\n",B);

    return 0;
}

int ch_data(int N,int M, int L,int K){
    if((N*M<=300)&&(M*L<=300)&&(K*L<=300)){
        return 1;
    }
    else return 0;
}

void numbers_for_my_array(const int rows, const int cols, int arr[rows][cols])
{
    int i,j;
    for (i=0;i<rows;i++){
        for(j=0;j<cols;j++){
            arr[i][j]=rand()%100;
        }
    }

}


void print_my_array(const int rows, const int cols, const int arr[rows][cols])
{
    int i, j;
    for(i=0;i<rows;i++)
    {
        for(j=0;j<cols;j++)
        {
            printf("%d ", arr[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

void min_my_array(const int rows, const int cols, const int arr[rows][cols], int *min_i, int *min_j, int *min_value)
{
    int i, j,min_a;
    min_a=arr[0][0];
    *min_value = min_a;
    for(i=0;i<rows;i++)
    {
        for(j=0;j<cols;j++)
        {
            if (my_mod(arr[i][j])<min_a)
            {
                min_a = my_mod(arr[i][j]);
                *min_value = arr[i][j];
                *min_i = i;
                *min_j = j;
                *min_value=min_a;
            }
        }
    }
}

int comp_my_array (int min_value_a,int min_value_b,int min_value_c){

    int s1,s2,s3;
    s1=min_value_a;
    s2=min_value_b;
    s3=min_value_c;
    return (s1> s2)? ((s1>s3)? s1 : s3) : ((s2 > s3)? s2 : s3);
}

int my_mod(int x){
    return (x>=0)? x:-x;}
Community
  • 1
  • 1
ad absurdum
  • 19,498
  • 5
  • 37
  • 60
  • Sorry, can you tell me one more time about srand? – Nikita Gusev Dec 15 '16 at 19:45
  • @NikitaGusev-- you only need to call `srand()` once to seed `rand()`. You can place this call right after your declarations at the beginning of `main()`. The problem you were having is that by calling `numbers_for_my_array()` three times in quick succession, the value returned by `time()` had not yet been updated (the return value is in seconds). Consequently, you were seeding `rand()` with the same number again, and thus generating the same list of pseudo-random numbers. – ad absurdum Dec 15 '16 at 19:56
  • Thanks, and the last, if you can void numbers_for_my_array(const int rows, const int cols, const int arr[rows][cols]) { int i,j; for ( i=0;i – Nikita Gusev Dec 15 '16 at 20:06
  • @NikitaGusev-- That was my mistake. I should have removed the `const` qualifier from `arr` in the function prototype, since this function actually modifies the array. I will update my answer. – ad absurdum Dec 15 '16 at 20:09
  • Okay, i will do it my own, but i'd like to chek myself , if you change your answer – Nikita Gusev Dec 15 '16 at 20:14
  • can i show you my code in facebook for example, please – Nikita Gusev Dec 15 '16 at 20:21
  • @NikitaGusev-- I am not on facebook. I had to remove the `const` qualifiers from all of the arrays to get this to compile. I went ahead and modified your original code to use VLAs, and added the new code to the end of my answer. The new code seems to work. Let me know if you have more questions :) – ad absurdum Dec 15 '16 at 20:42
  • Thanks for your helping a lot! I just say WOW ahah! thaaaaaaaaaaanks! – Nikita Gusev Dec 15 '16 at 20:56
  • @NikitaGusev-- I have added a discussion of the problems in lifting an array to `const` in a function call, included a link to further discussion, and modified the code so that the function calls use 2D arrays of `const int` now. – ad absurdum Dec 15 '16 at 21:41