Home > Back-end >  Function "read()" forces the program to exit when typing information into dynamically allo
Function "read()" forces the program to exit when typing information into dynamically allo

Time:01-24

Okay so I have a simple code here that is troubling me:

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

    typedef struct file{
    char name[20], extension[6];
    int s; // size in bytes
    }FILE;

    FILE read_file()
    {
      FILE u;

      printf("\nEnter file name: ");
      scanf("\n%s", u.name);

      printf("Extension: ");
      scanf("\n%s", u.extension);

      printf("Size in bytes: ");
      scanf("\n%d", u.s);

      return u;
    }

    void sort(FILE* arr, int n)
    {
      for(int i=0; i<n; i  )
      {
        for(int j=0; j<n-1; j  )
        {
            if(arr[i].s < arr[j].s)
            {
                FILE pom = arr[i];
                arr[i] = arr[j];
                arr[j] = pom;
            }        
        }
      }
    }

    int main(void)
    {
      int n;

      printf("Enter a num. of files: ");
      scanf("%d", &n);

      FILE* pn = (FILE*)malloc(n * sizeof(FILE));
      for(int i=0; i<n; i  )
      {
        printf("%d. file:", i 1);
        read_file(pn i);
      }

      sort(pn, n);

      printf("\nNum.     File name      Extension      Size");
      printf("\n===   ==============   ===========   ========");
      for(int i=0; i<n; i  )
      {
        printf("\n%-4d %-22s %-12s %d", i 1, pn->name, pn->extension, pn->s);
      }
    }

Code runs fine when you type in the information for the first file in the dynamically allocated array, but as soon as you need to enter information for the second file, the code exits.

This part over here:

for(int i=0; i<n; i  )
    {
        printf("%d. file:", i 1);
        read_file(pn i);
    }

I believe that I have to declare a variable of FILE data type which function "read()" will return, but the compiler still shows error even though I (let's presume) declare:

FILE p = read_file(pn i);

Edit!

Renamed "read()" function to "read_file()".

I would gladly appreciate any help. Thank you in advance!

CodePudding user response:

The code presented has at least these major problems:

  1. If you #include <stdio.h> then you may not define FILE as an ordinary identifier, including a typedef name. Doing so violates a language constraint, so a conforming compiler is obligated to emit a diagnostic about that. If it accepts the code then the resulting behavior is undefined.

  2. Given that u.s has type int, the call

        scanf("\n%d", u.s);
    

    is wrong and produces undefined behavior. The intended function call appears to have been

        scanf("\n%d", &u.s);
    

    There is a better than average probability that the UB attending this mistake would manifest as a program crash. Some C compilers would have diagnosed this error for you, so if yours did not (you are compiling this locally for testing purposes, right?) then you should consider getting a better compiler.

  3. The function call read_file(pn i); is incorrect because function read_file() does not accept any arguments. Even a pretty poor C compiler ought to have issued a diagnostic about that, so either you are not paying attention to the compiler's diagnostic messages or you are in desperate need of a better compiler. Typically, however, the UB associated with an error of this kind does not manifest as a program crash, and might not have a perceivable manifestation at all.

There is also this lesser issue:

  1. The program ignores the return value of read_file(). This is allowed, but it is not what you appear to want do. The result is that the data that are read are not written to the object to which your pn pointer points. The program output should give evidence of this.

CodePudding user response:

The code

FILE* pn = (FILE*)malloc(n * sizeof(FILE));

is actually allocate a memory space for a pointer of "FILE". In this memory space resides only one pointer. If you dereferencing that pointer, you can only access one "FILE".

If you want to allocate memory for an array of "FILE"s. I suggest that you allocate a memory space for an array of pointer of "FILE". For example

FILEx** pn_arr = (FILEx**)malloc(n * sizeof(FILEx*));

In this space, you keep n pointers of "FILE" that you can track each file by the pointer of pointer "pn_arr".

Then, each time you try to assign data to a "FILE". You should allocate a new space to it. For example:

FILEx* pn = (FILEx*)malloc(sizeof(FILEx));

I try to fix your problem. Mine implementation is as following:

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

typedef struct file{
    char name[20], extension[6];
    int s; // size in bytes
}FILEx;

void read_file(FILEx* pn)
{
    printf("\nEnter file name: ");
    scanf("\n%s", pn->name);

    printf("Extension: ");
    scanf("\n%s", pn->extension);

    printf("Size in bytes: ");
    scanf("\n%d", &pn->s);
}



 int main(void)
{
   int n;

   printf("Enter a num. of files: ");
   scanf("%d", &n);

   FILEx** pn_arr = (FILEx**)malloc(n * sizeof(FILEx*));

  for(int i=0; i<n; i  )
  {
     printf("%d. file:", i 1);
     FILEx* pn = (FILEx*)malloc(sizeof(FILEx));
     read_file(pn);
     pn_arr[i] = pn;
   }

 //sort(pn, n);

 printf("\nNum.     File name      Extension      Size");
 printf("\n===   ==============   ===========   ========");
 for(int i=0; i<n; i  )
 {
    printf("\n%-4d %-22s %-12s %d", i 1, pn_arr[i]->name
    , pn_arr[i]->extension, pn_arr[i]->s);
 }
}

Note that I didn't test your sort() function. If you are going to use pointer of pointer to implement the array of "FILE". You should modify your sort() function to make it work. I think that will be easy to implement a sort() function if you use pointer of pointer to keep track of "FILE". Because you just need to exchange pointer to rearrange the order of "FILE".

  •  Tags:  
  • Related