LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   most puzzling seg fault bug (https://www.linuxquestions.org/questions/programming-9/most-puzzling-seg-fault-bug-4175541377/)

retroCheck 05-01-2015 09:09 PM

most puzzling seg fault bug
 
I have a wierd situation. When I add a new var to the main(){} of my program I get a seg fault error. So if I was to add this to the code below: int myNewVar = 0;
I would get a seg fault, otherwise program is fine. Any help would be awesome I have been fighting this for some time now. Thanks

Code:

#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <queue>
using namespace std;

struct Process{
        int pid;
        int arrival;
        int burst;
};
float trn_avg;
int FCFS(queue<Process> q,float *ptr_wait, float *ptr_thr_put,int sim_time);
void sort_queue(queue<Process> q);
int SJF(queue<Process> q,float *ptr_wait, float *ptr_thr_put,int sim_time);
int find_lrg(queue<Process> q);
int main(int argc, char **argv){
        int p_remain = 0;
        float *ptr_wait;
        *ptr_wait = 0;
        float thr_put = 0;
        float *ptr_thr_put;
        *ptr_thr_put = 0;
        bool first = true;
        int sim_time;

        //argument check
        if(argc == 3 || argc == 4){
                sim_time = strtol(argv[1],NULL,10);
                string algorithm = argv[2];
                if(argc == 4){
                        int time_slice = strtol(argv[3],NULL,10);
                }
        }else{//incorrect amount of arguments
                fprintf(stderr,"usage:./hw4 sim_time algorithm [time_slice]\n");
                exit(1);
        }

       
        queue<Process> proc_que;//queue to hold processes
        Process proc;//struct to hold process data
        int count = 1;//keep track of data for incoming process line
        int i_proc;//input process
        while( cin >> i_proc){
               
                switch (count) {
                case 1:
                        proc.pid = i_proc;//PID       
                        count++;
                        break;
                case 2:
                        proc.arrival = i_proc;//arrival time       
                        count++;
                        break;
                case 3:
                        proc.burst = i_proc;//CPU burst time
                        proc_que.push(proc);//struct data loaded,push to queue
                       
                        count = 1;//process struct loaded,count = 1 to start new struct
                        break;
                default:
                        cout << "Nothing entered into struct" << endl;
                        break;
                }
}


        p_remain = FCFS(proc_que,ptr_wait,ptr_thr_put,sim_time);//First come first serve
                cout << endl << "Throughput = " << *ptr_thr_put << endl;
                cout << "Avg wait time = " << *ptr_wait << endl;
                cout << "Avg turnaround time = " << trn_avg << endl;
                cout << "Remaining tasks =  " << p_remain << endl;

                //find_lrg(proc_que);       
return 0;
}

//function for first come first serve algorithim.
int FCFS(queue<Process> q,float *ptr_wait, float *ptr_thr_put,int sim_time){
        Process p;
        float cmtv_wait = 0;
        float cmtv_trn_time = 0;
        float old_burst = 0;
        float st_end = 0;
        int q_size = q.size();

        float time = 0;       
        float wait_time = 0;
        float turn_time = 0;
        for(int i = 0; i < q_size; i++){
                p = q.front();
                q.pop();
                //ensure that there is enough time left
                if(time + p.burst <= sim_time){
                //schedule/terminate printout
                cout << " " << *ptr_wait << ": scheduling PID " << p.pid << ", CPU = " << p.burst << endl;
                cout << " " << *ptr_wait + p.burst  << ": PID " << p.pid << ", terminated" << endl;
                (*ptr_thr_put)++;
                time = time + p.burst;
                *ptr_wait = time;
               
               
                //avg wait time calc
                wait_time += time;
                }else{
                        break;
                }               

        }

                        //avg turn around time calc
                        turn_time = wait_time;
                        //do not need last time 
                        wait_time -= time;
                        //clac avg turnaround time for final stats
                        trn_avg = turn_time/(*ptr_thr_put);
                        //calc avg wait time for final stats
                        *ptr_wait = wait_time/((*ptr_thr_put));       
                        return q_size - (*ptr_thr_put);
}       



int SJF(queue<Process> q,float *ptr_wait, float *ptr_thr_put,int sim_time){
        Process p;
        float cmtv_wait = 0;
        float cmtv_trn_time = 0;
        float old_burst = 0;
        float st_end = 0;
        int q_size = q.size();

        float time = 0;       
        float wait_time = 0;
        float turn_time = 0;
        for(int i = 0; i < q_size; i++){
                p = q.front();
                q.pop();
                //ensure that there is enough time left
                if(time + p.burst <= sim_time){
                //schedule/terminate printout
                cout << " " << *ptr_wait << ": scheduling PID " << p.pid << ", CPU = " << p.burst << endl;
                cout << " " << *ptr_wait + p.burst  << ": PID " << p.pid << ", terminated" << endl;
                (*ptr_thr_put)++;
                time = time + p.burst;
                *ptr_wait = time;
               
               
                //avg wait time calc
                wait_time += time;
                }else{
                        break;
                }               

        }

                        //avg turn around time calc
                        turn_time = wait_time;
                        //do not need last time 
                        wait_time -= time;
                        //clac avg turnaround time for final stats
                        trn_avg = turn_time/(*ptr_thr_put);
                        //calc avg wait time for final stats
                        *ptr_wait = wait_time/((*ptr_thr_put));       
                        return q_size - (*ptr_thr_put);
}

int find_lrg(queue<Process> q){       
        Process prc;
        int brst = 0;
        int temp = 0;
        int q_size = q.size();
        for(int i = 0; i < q_size; i++){
                prc = q.front();
                q.pop();
                brst = prc.burst;
                if(brst > temp){
                        temp = brst;       
                }
        }
        cout << "this is lrg " << temp;
        return temp;
}


NevemTeve 05-02-2015 12:38 AM

You seems to have uninitalized variables in 'main':

Code:

        float *ptr_wait;
        *ptr_wait = 0;

        float *ptr_thr_put;
        *ptr_thr_put = 0;

that's plain wrong, a quick fix:

Code:

        float ptr_wait = 0;
        float ptr_thr_put = 0;


johnsfine 05-02-2015 06:23 AM

Quote:

Originally Posted by NevemTeve (Post 5356524)
a quick fix:

That is not enough of a correction. If you take that approach, you would need to correct all the uses of each of those two variables within main().

Correcting all those uses, so each variable is a float within main() but a float* everywhere else, is a bit more efficient than the alternative I'm about to suggest. But the following is less of a change and it keeps the usage consistent between main() and the rest of the code, which may make the program more maintainable.

Instead of:
Code:

  float *ptr_wait;
  *ptr_wait = 0;

  float *ptr_thr_put;
  *ptr_thr_put = 0;

use:
Code:

  float val_wait=0
  float *ptr_wait = &val_wait;

  float val_thr_put=0;
  float *ptr_thr_put = &val_thr_put;

This is a common source of confusion for beginners in C programming. You have a function (typically spec'ed by someone else) that must take an XYZ* as a parameter. So in the function that must call that, a beginner only declares a XYZ* and initializes only the value pointed to and then passes that. But unless you initialize the pointer itself, you don't have any value pointed to and you usually get a seg fault.

The efficient solution (in some more advanced cases the only good solution) is to use an XYZ (instead of an XYZ*) within the top level function and pass &name instead of name to any function that needs an XYZ*

The simplest solution, as I showed above, is to declare and initialize an XYZ and use its address to initialize the pointer.

The common solution is to use malloc. Sometime that is best, but it is more popular (as compared to the simpler solution) than it ought to be.
Code:

  float* ptr_wait = (float*)malloc( sizeof(float) );
  *ptr_wait = 0;

or, since this seems to be C++
Code:

  float* ptr_wait = new float(0);

retroCheck 05-02-2015 06:39 AM

Thank you very much! That was the problem. Do you know why it was that only when I added a new variable that I would get the seg fault?

pan64 05-02-2015 08:57 AM

Those non-initialized variables have usually got a something like a random value. The memory area of those variables were earlier in use (probably). Adding another variable will cause only one thing, the variables will be stored in another part of the memory, therefore will get another "initial" value. So in your example in the first case the memory contained something usable, and in the second case the memory (where those variables were stored) contained invalid values.

retroCheck 05-02-2015 09:07 AM

I see, thank you.


All times are GMT -5. The time now is 07:28 PM.