Thread: Segmentation Fault

  1. #1
    Registered User
    Join Date
    Sep 2003
    Posts
    16

    Segmentation Fault

    Hey guys. I'm working on making a round robin process scheduling algorithm and I'm working on it bit by bit. However, I seem to have hit a snag. The following code gives me a segmentation fault after the outputs have displayed. I'm sure I'm missing something completely obvious, but I don't see it.

    The data file is located here:
    Data file
    The pogram takes the time quanta and context switch time as arguments, eg. "rr 5 5" is 5 ms burst and 5 ns sontext switch.

    Here is my code:
    Code:
    #include <iostream>
    #include <fstream>
    using namespace std;
    
    /* Process Data Structure */
    struct process {
        int arrive;             /* Process Arrival Time */
        int burst;              /* CPU Burst Time */
        float working;            /* Working time*/
        float waiting;            /* Waiting time*/
        struct process *next;
    };
    
    struct process *init_process (int pid, int burst);
    float rr (struct process *proc);
    
    int  main(int argc, char* argv[]) {
    
    	struct process *plist,*ptmp;
    
    	int init = 0;
    	int quanta = (int) argv[1];
    	int context_switch = (int) argv[2];
    	float cswitch = context_switch/100;
    
    	ifstream input;
    	input.open("rrdata.txt");
    	if (input.fail()) {
           cerr << "unable to open file rrdata.txt for reading" << endl;
           exit(1);
    	}
    	ofstream output;
    	output.open("output.txt");
    	if (output.fail()) {
           cerr << "unable to open file output.txt" << endl;
           exit(1);
    
    	}
    
    	
    
    	//Initialize  the list of processes
    	int arrive,burst;
    	input>>arrive>>burst;
    	output<<arrive<<' '<<burst<<endl;
    	plist = init_process(arrive,burst);
      init++;
      input>>arrive>>burst;
      plist -> next = init_process(arrive,burst);ptmp = plist->next;
      init++;
      output<<arrive<<' '<<burst<<endl;
      for (int i = 0; i < 97; i++) {
        input>>arrive>>burst;
        ptmp -> next = init_process(arrive,burst);ptmp = plist->next;
        init++;
        output<<arrive<<' '<<burst<<endl;
        }
      input>>arrive>>burst;
      ptmp -> next = init_process(arrive,burst);          
    	init++;
      output<<arrive<<' '<<burst<<endl;
      cout<<init<<endl;
    	cout<<argv[1]<<' '<<argv[2]<<endl;
      float avgburst = rr(plist);
    	return 0;
    }
    
    struct process *init_process (int arrive, int burst) {
    	struct process *proc;
    	proc = (struct process*) malloc(sizeof(struct process));
        if (proc == NULL) {
            printf("Fatal error: memory allocation failure.\nTerminating.\n");
            exit(1);
         };
        proc->arrive = arrive;
        proc->burst = burst;
        proc->working = 0;
        proc->waiting = 0;
        proc->next = NULL;
        return(proc);
    };
    
    float rr (struct process *proc){
      float burst = 0;
      for(int i=0; i<5; i++){
      burst = burst + proc->burst;
      proc = proc -> next;
      }
      return(burst/100);
     
    };
    Last edited by Shinobi-wan; 12-19-2004 at 07:37 AM.

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >int quanta = (int) argv[1];
    >int context_switch = (int) argv[2];
    >float cswitch = context_switch/100;
    None of these will work like you want them to. Simply casting a string to int doesn't perform a conversion. To actually convert a string to int (without using atoi because it sucks), you need to use strtol:
    Code:
    #include <cstdlib>
    
    int quanta = static_cast<int>(std::strtol(argv[1], NULL, 0));
    int context_switch = static_cast<int>(std::strtol(argv[2], NULL, 0));
    Of course, it's also a very good idea to verify your assumption that argc is at least 3. The reason cswitch won't work is because you're using integer division, which truncates and precision in the value. So if context_switch is less than 100, the result will be 0.

    >The following code gives me a segmentation fault after the outputs have displayed.
    That's a hint. What do you do after the results are displayed?
    Code:
    float avgburst = rr(plist);
    return 0;
    Okay, you can either assume that something is going wrong in rr, or you've managed to corrupt memory so that the cleanup code after returning from main crashes. Let's look at rr first though. There's not much there, so it's a safe bet that the problem would be here:
    Code:
    for(int i=0; i<5; i++){
    And the symptom of the problem (segmentation fault) would be here:
    Code:
    burst = burst + proc->burst;
    Most likely, your list isn't 5 nodes long. You're walking off the end into a null pointer and then trying to dereference that pointer. If this short list is the correct behavior then you need to account for it by changing your loop:
    Code:
    while (proc != NULL) {
    If you really were expecting a 5 node list for correct operation, then your logic is wrong somewhere.
    My best code is written with the delete key.

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    just from a quick look i'm guessing the seg fault is in rr()....you should check to make sure there is a proc->next before setting proc to proc->next.

    a few other points:
    1. use "new" instead of malloc
    2. no need for "struct" any more. this works fine
    Code:
    struct xyz{ int i; int j; };
    xyz mystructure;
    3. unless you just want to play with linked lists, i suggest using a vector
    4. close your files. being an automatic object the destructors
    should do it for you, but i think it's a good idea to make sure.
    Last edited by misplaced; 12-19-2004 at 08:32 AM.
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  4. #4
    Registered User
    Join Date
    Sep 2003
    Posts
    16
    All right. I added in some of the suggested things, and I added in an exit condition into rr(). The condition is triggeresd all the time, so I need to figure that out. Any suggestions?

    Also, my arguments for my program are always going to be two arguments greater then 5.

    I need to go over to the doctor. My sickness may be contributing to my sloppy coding. I'll be back in a few hours. :P Here's what I have now.

    Code:
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    using namespace std;
    
    /* Process Data Structure */
    struct process {
        int arrive;             /* Process Arrival Time */
        int burst;              /* CPU Burst Time */
        float working;            /* Working time*/
        float waiting;            /* Waiting time*/
        process *next;
    };
    
    process *init_process (int pid, int burst);
    float rr (process *proc);
    
    int  main(int argc, char* argv[]) {
    
    	process *plist,*ptmp;
    	int init = 0;
    	int quanta = static_cast<int>(std::strtol(argv[1], NULL, 0));
    	int context_switch = static_cast<int>(std::strtol(argv[2], NULL, 0));
    	float cswitch = context_switch/100;
    
    	ifstream input;
    	input.open("rrdata.txt");
    	if (input.fail()) {
          cerr << "unable to open file rrdata.txt for reading" << endl;
          exit(1);
    	}
    	ofstream output;
    	output.open("output.txt");
    	if (output.fail()) {
          cerr << "unable to open file output.txt" << endl;
          exit(1);
    	}
    
    	//Initialize  the list of processes
            int arrive,burst;
    	input>>arrive>>burst;
    	output<<arrive<<' '<<burst<<endl;
    	plist = init_process(arrive,burst);
      init++;
      input>>arrive>>burst;
      plist -> next = init_process(arrive,burst);ptmp = plist->next;
      init++;
      output<<arrive<<' '<<burst<<endl;
      for (int i = 0; i < 97; i++) {
        input>>arrive>>burst;
        ptmp -> next = init_process(arrive,burst);ptmp = plist->next;
        init++;
        output<<arrive<<' '<<burst<<endl;
        }
      input>>arrive>>burst;
      ptmp -> next = init_process(arrive,burst);          
    	init++;
      output<<arrive<<' '<<burst<<endl;
    
      cout<<init<<endl;
    	cout<<argv[1]<<' '<<argv[2]<<endl;
    
      float avgburst = rr(plist);
    	input.close();
    	output.close();
    	return 0;
    
    }
    
    struct process *init_process (int arrive, int burst) {
    	struct process *proc;
    	proc = new struct process;
        if (proc == NULL) {
            printf("Fatal error: memory allocation failure.\nTerminating.\n");
            exit(1);
         };
        proc->arrive = arrive;
        proc->burst = burst;
        proc->working = 0;
        proc->waiting = 0;
        proc->next = NULL;
        return(proc);
    };
    
    float rr (process *proc){
      float burst = 0;
      for(int i=0; i<5; i++){
      burst = burst + proc->burst;
    	if (proc -> next == NULL){
    		cerr<<"CANNOT CONTINUE SUMMATION. ENDING."<<endl;
    		return 0;
    		}
      proc = proc -> next;
      }
    
      return(burst);
             
    };

  5. #5
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    Quote Originally Posted by Shinobi-wan
    The condition is triggeresd all the time, so I need to figure that out. Any suggestions?
    uh, yea, my suggestion is to read prelude's post again
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  6. #6
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by Shinobi-wan
    All right. I added in some of the suggested things, and I added in an exit condition into rr(). The condition is triggeresd all the time, so I need to figure that out. Any suggestions?
    Maybe you can figure out what's wrong with it by seeing what's really in your list. You could try something like this:

    Code:
    float rr (process *proc){
      float burst = 0;
      for(int i=0; i<5; i++){
        cout << i 
             << ": proc->arrive = " << proc->arrive
             << ", proc->burst = " << proc->burst << endl;
        burst = burst + proc->burst;
        if (proc -> next == NULL){
          cerr<<"i = " << i << ",  CANNOT CONTINUE SUMMATION. ENDING."<<endl;
          return 0;
        }
        proc = proc -> next;
      }
    
      return(burst);
             
    };

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Also, my arguments for my program are always going to be two arguments greater then 5.
    Can you prove that? What if you give the program to someone else to use? That's a really bad excuse for shoddy coding, but who am I to tell you otherwise.

    >Any suggestions?
    Well, it doesn't seg fault anymore...
    My best code is written with the delete key.

  8. #8
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    Quote Originally Posted by Prelude
    >Any suggestions?
    Well, it doesn't seg fault anymore...
    lol...you're such a....
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  9. #9
    Registered User
    Join Date
    Sep 2003
    Posts
    16
    I'm back. Turns out that our insurance is an HMO which only covers a doctor who dosen't have hours today. peachy...

    So anyway, I looked back and saw my obvious mistake... I had my ptmp going through the list, connecting the nodes of the queue...but I was always assigning ptmp to plist ->next...which meant I had a whole queue of nodes who were pointing to the 2nd node in the queue. Not too useful.

    Thanks guys. If I need any more help, I'll post here again.

  10. #10
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Hmmmm this thread predates the other. And the other (which despite my rewriting a lot of your code, you gave me negative feedback) had pretty much all of the problems you said you had here, plus still had the problems that Prelude had warned you about. By the way, if you require command line arguments tell the user! I had no idea it required arguments when I first ran the code you posted on the other thread. If you notice in my revision it at the very least doesn't attempt execution unless the arguments are there.

    Your other problem that was leading to problems to occur was the fact that you never made sure memory was being allocated. If you haven't already done so, I highlighted what needs to be fixed. Instead of flaming me for only telling you where your code is broken, how about not expected us to do all of your work for you?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault problem
    By odedbobi in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2008, 03:36 AM
  2. Segmentation fault
    By bennyandthejets in forum C++ Programming
    Replies: 7
    Last Post: 09-07-2005, 05:04 PM
  3. Segmentation fault
    By NoUse in forum C Programming
    Replies: 4
    Last Post: 03-26-2005, 03:29 PM
  4. Locating A Segmentation Fault
    By Stack Overflow in forum C Programming
    Replies: 12
    Last Post: 12-14-2004, 01:33 PM
  5. Segmentation fault...
    By alvifarooq in forum C++ Programming
    Replies: 14
    Last Post: 09-26-2004, 12:53 PM