Thread: Program Crashes

  1. #1
    Registered User
    Join Date
    Aug 2012
    Posts
    6

    Program Crashes

    Hello,

    I am a beginner for C Programming and is taking an introductory course over the summer. Right now I'm having some trouble with this programming assignment where it asks me to enter a resistance and voltage value for the input in order to calculate the min, max, and avg values for the voltage, current, and power across a network of resistors by using arrays and functions. But when I tried to compile my program, it crashes when I enter any input values. Here is my code below:

    Code:
    #include <stdio.h>
    
    int ReadRes(int n, double *r, double *v);                                                // The function that will read the resistance and voltage. *r and *v are pointers while n is the resistor #.
    
    void MinMaxAvg(double x[], int n, double *min, double *max, double *avg);                // The function that will calculate the quantities for each input as the pointers included in this function will end up being used to calculate the outputs.
    
    int main ()    {
        
    double R, V, I_min, P_min, V_min, I_max, P, P_max, V_max, I_avg, P_avg, V_avg;
        
    double I; // Current values
        
    int n; // # of elements in array
        
    
    /* R and V are the resistance and voltage values to be entered by the user. 
        The other declared double variables will be used to calculate the min, max, and avg for current and power. */
        
    
    for (n = 1; n <= 20; n++)    {
            printf(
    "Enter R and V for resistor %d: ", n);
            ReadRes(n, &R, &V);
            
    // Calculate min, max, and average values for current
            MinMaxAvg(&V, n, &V_min, &V_max, &V_avg);
            
            I = V / R;
            
            MinMaxAvg(&I, n, &I_min, &I_max, &I_avg);
            P = V * I;
            MinMaxAvg(&P, n, &P_min, &P_max, &P_avg);
                    
            printf("    Voltage        Current        Power\n");
             printf("MIN       %.4lf   %.4lf   %.4lf\n", V_min, I_min, P_min);
            printf("MAX       %.4lf   %.4lf   %.4lf\n", V_max, I_max, P_max);
            printf("AVG       %.4lf   %.4lf   %.4lf\n", V_avg, I_avg, P_avg);
            }
        
    return 0;
    }
    
    
    int ReadRes(int n, double *r, double *v)    {
        
    int scanfRetVal = scanf("%lf %lf", *r, *v);
        
    while (1)    {
            
    if (*r > 0)    {
                
    if (scanfRetVal < 2)    {
                    
    return -1;
                }
                
    else
                    
    if (scanfRetVal == EOF)    {
                    
    return 0;                        // Indicates no valid data read
                    
    break;
                    }
                    
    else
                        
    return 1;
                        
    break;
            }
            
    else
        printf("Error: R must be greater than 0\n");
        }
    }
    
    void MinMaxAvg(double x[], int n, double *min, double *max, double *avg)    {
        
    int i;
        
    double sum;
        sum = 0;
        *min = x[0];
        
    for (i = 0; i < n; i++)    {
            
    if (x[i] < *min)
                *min = x[i];
        }
        *max = x[0];
        
    for (i = 0; i < n; i++)    {
            
    if (x[i] > *max)
                *max = x[i];
        }
        
        
    for (i = 0; i < n; i++)    {
            sum += x[i];
        }
        *avg = sum / n;
    }
    

    Another thing to note about this program is that when the user enters CTRL-Z to end the loop, the main program should look at the return value from ReadRes() function and use it to determine what to do next.

    In case you need to know what the output of this program should turn out to be it should look something like this:

    Attachment 11910

    So what's causing my program to crash? Any help would be greatly appreciated. Thanks.

  2. #2
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    Program crashes when input is given,so you should check the part where the input is handled by your code.Indeed,in function redRes where input is handled,the scanf is not called as it ought to be.When scanf if called we tend to pass the addresses of the arguments.Here the variables you want to pass to scnaf are with pointers(*).So when you write *r you refer to the value of r.So how are you going to refer to the adress of it?By typing r.Try this.If you have any question please ask!
    Also i saw that n is not used in redRes function.So why do you pass it as an argument?

    PS-Welcome to the forum

  3. #3
    Registered User
    Join Date
    Aug 2012
    Posts
    6
    Hi! So I followed your procedure (not sure I did it correctly) and now I'm stuck at a runtime error #3 where the variable scanfRetVal is uninitialized. My question is, am I supposed to put the scanf in the main function or in the ReadRes function? What happened was I put the scanf in the main function and then I followed it up by using the ReadRes function after it.

  4. #4
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    I think that it very elegant to have a function that fully handles input.So my suggestion is to put the scanf inside the function.If you wish ,you may post your code here in order to find the problem

  5. #5
    Registered User
    Join Date
    Aug 2012
    Posts
    6
    Okay so here's what I've come up with so far. The code below only deals with the main function.

    Code:
    for
     (n = 1; n <= 20; n++)    {
    
            printf(
    "Enter R and V for resistor %d: ", n);
    
            scanfRetVal = scanf(
    "%lf %lf", &R, &V);
    
            ReadRes(&R, &V);
    
    The other code below deals with the ReadRes function.

    Code:
    int
     ReadRes(double *r, double *v)    {
    
        
    int scanfRetVal;
    
        scanfRetVal = scanf(
    "%lf %lf", *r, *v);
    
    
        
    while (1)    {
    
            
    if (*r > 0)    {
    
                
    if (scanfRetVal < 2)    {
    
                    
    return -1;
    
                }
    
                
    else
    
                    
    if (scanfRetVal == EOF)    {
    
                    
    return 0;                        // Indicates no valid data read
    
                    
    break;
    
                    }
    
                    
    else
    
                        
    return 1;
    
                        
    break;
    
            }
    
            
    else
    
                printf(
    "Error: R must be greater than 0\n");
    
        }
    
    }
    
    


  6. #6
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    You mean you call scanf twice per resistor?That's wrong.You should call it once per resistor(either in main or in function(i recommend it)).

  7. #7
    Registered User
    Join Date
    Aug 2012
    Posts
    6
    Ah my bad. So I removed the scanf from the main function, but now when I compile, the program crashes again. Do you know what the problem is?

  8. #8
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    The problem is what i posted you from start.Inside the function you do not call the scanf as you ought to do!You should pass the adrresses of the variables,not the values of them
    Here the program crashes
    Code:
      scanfRetVal = scanf(
    "%lf %lf", *r, *v);
    Useful tip : Use printf functions where you think your code might has errors.This way you find at exactly which line your program crashes.
    e.g.
    Code:
    ..
    printf("here\n");
    a line of code with no problem
    printf("here1\n");
    the line where your program crashes!!!
    printf("here2\n");
    ....
    the output will be
    Code:
    here
    here1
    -then the program crashes(this will not be shown in screen of course)
    This way you are able to spot the line that causes your program to crash.
    Have questions?Ask

  9. #9
    Registered User
    Join Date
    Aug 2012
    Posts
    6
    From my understanding of what you meant, I got rid of the pointers (*) from the ReadRes function. But by doing that now I got another runtime error where the local variable V is being uninitialized. Here's what I have so far.

    Code:
    for
     (n = 1; n <= 20; n++)    {
    
            printf(
    "Enter R and V for resistor %d: ", n);
    
            ReadRes(R, V); // the error occurs here
    
    


    And here's the revised code of the function.

    Code:
    
    int
     
     
     
     ReadRes(double r, double v)    {
    
     
        
     
     
    int scanfRetVal;
    
     
        scanfRetVal = scanf(
     
     
    "%lf %lf", &r, &v);

  10. #10
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    You have to remember two important things
    • scanf(because of her prototype(The C Library Reference Guide at 2.12.4.2 ) you have to pass the arguments by their addresses,not by their value.
      e.g.
      Code:
      #include <stdio.h>
      
      int main(void)
      {
          int number;
          printf("Please enter a number\n");
          scanf("%d",&number);
          printf("Number given is %d\n",number);
          return 0;
      }
      Output
      Code:
      Please enter a number : 5
      Number given is 5
    • Mind that * and & when written together deactivate each other.
      e.g. You have a function print which needs the argument by value.See the code
      Every human programmer ( ) would write something like this
      Code:
      #include <stdio.h>
      
      void print(int n);
      
      int main(void)
      {
          int number;
          printf("Please enter a number : ");
          scanf("%d",&number);
          print(number);
          return 0;
      }
      
      void print(int n)
      {
          printf("Number given is %d\n",n);
      }
      However you could call function print like this(not recommended)
      Code:
      print(*&number);
      The point is that print(*&number) is equivalent to print(number).So the postscript is that operators * and & kill each other!
    • When you want a function to maintain the changes in values of arguments that are passed to her,even after the function is terminated you have to pass the argument by reference.Otherwise the modifications made to argument are lost when the function terminates
      e.g.
      Code:
      #include <stdio.h>
      
      void test(int val,int arg);
      void modificationsRemain(int *val,int *arg);
      
      int main(void)
      {
          int a,b;
          a=5;
          b=6;
          test(a,b);
          printf("After function test : a= %d and b= %d\n",a,b);
          modificationsRemain(&a,&b);
          printf("After function modificationsRemain : a= %d and b= %d\n",a,b);
          return 0;
      }
      
      void test(int val,int arg)
      {
          val=1000;
          arg=2727;
      }
      
      void modificationsRemain(int *val,int *arg)
      {
          *val = 55;
          *arg = 66;
      }
      and the output is
      Code:
      After function test : a= 5 and b= 6
      After function modificationsRemain : a= 55 and b= 66
    • Back to first part of code i wrote,we are going to use scanf inside a function.Let's see the code
      Code:
      #include <stdio.h>
      
      void print(int n);
      /*Argument passed by reference in order 
       * to maintain modifications*/
      void input(int *n);
      
      int main(void)
      {
          int number;
          printf("Please enter a number : ");
          input(&number);
          print(number);
          return 0;
      }
      
      void input(int *n)
      {
          scanf("%d",n);
      }
      
      void print(int n)
      {
          printf("Number given is %d\n",n);
      }
      and the output
      Code:
      Please enter a number : 5
      Number given is 5
      So why do we call scanf with just n and not &n?Because inside the body of the function input,the value of n is accessed by
      Code:
      *n
      so we need the address of n,so actually what we are doing is to request for the address by writting
      Code:
      scanf("%d",&*n);
      but because & and * kill each other(and vice versa) we simply write
      Code:
      scanf("%d",n);
      Better now?Try to understand what i said and apply these to your code.If questions are in your head do not hesitate to post back
    Last edited by std10093; 08-19-2012 at 07:24 PM.

  11. #11
    Registered User
    Join Date
    Aug 2012
    Posts
    6
    That helps A LOT! Thank you so much! That explanation right there helped me to finally fix those crash issues as well as the errors I keep getting. I really appreciate it.

    And my apologies for misunderstanding your previous messages, I'm still in the learning process of understanding how pointers work exactly because the topic is probably one of the most difficult to learn in C Programming.

  12. #12
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    No need to apology astroboy! Keep improving yourself

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Program crashes at very end
    By Kudose in forum C++ Programming
    Replies: 15
    Last Post: 07-23-2009, 04:06 AM
  2. My program crashes :|
    By Testify in forum C++ Programming
    Replies: 12
    Last Post: 06-27-2007, 11:48 AM
  3. Program crashes, why?
    By Mahdi123 in forum C Programming
    Replies: 5
    Last Post: 04-18-2007, 02:56 PM
  4. Odd program crashes
    By Mithoric in forum Windows Programming
    Replies: 3
    Last Post: 03-20-2004, 11:37 PM
  5. program crashes
    By Strut in forum Linux Programming
    Replies: 3
    Last Post: 02-10-2002, 10:49 AM