Segmentation fault occurring weirdly UPDATE

EDIT: I found a new segmentation fault.

I am getting a segmentation fault whenever I derefernce pointer entries to Segment object within segmentTable inside this function:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

void mySystem::snapshotDisk()
{
	vector< list<PCB*>* > disk_lists;
	devCtrl.allDiskQ(disk_lists);
	list<PCB*>* temp;

	cout << left << setw(5) << "PID" << setw(10) <<"File" << setw(10) << "Memstart" << setw(5) << "R/W" 
			 << setw(9) << "FileLen" << setw(11) << "TotalTime" << setw(9) << "AvgTime" <<  setw(5) << "Cyl" << setw(10) << "Seg(B, L)" << endl;;



	for(unsigned int i = 1; i <= disk_lists.size(); i++)
	{
		cout << endl << "----disk" << i << "(disk head at " << devCtrl.getCurrentCylinder(i) <<')' << endl;
		temp = disk_lists[i-1]; //get the (i-1)th disk list.

		if(!temp->empty())
		{
			list<PCB*>::iterator headPosition = *(devCtrl.getHeadPosition(i));
			list<PCB*>::iterator it = headPosition;

			//iterate starting from current head position
			for(; it != temp->end(); ++it)
			{
				cout << left << setw(5) << (*it)->getID() << setw(10) << (*it)->getFile() << setw(10) << (*it)->getMem() << setw(5) 
						 << (*it)->getAct() << setw(9) << (*it)->getFileLen() << setw(11) << (*it)->getTotalExecTime() << setw(9) 
						 << (*it)->getAvgCPUBurst() << setw(5) << (*it)->getCylinder();

				vector<Segment*> segmentTable = (*it)->segTable;

				for(unsigned int j = 0; j<segmentTable.size();  ++j )
				{
                                                //////////////////////////////////////////////
                                                //SEGMENTATION FAULT IN BELOW COUT STATEMENT
                                                //////////////////////////////////////////////
						cout << left << '(' << segmentTable[j]->base_ << ", " << segmentTable[j]->limit_ << ") ";

					if(j==1)
						cout << endl << setw(64) << "" ;

				}

				cout << endl;
			}

			it = temp->begin();

			//c-look wrap-around
			for(; it != headPosition; ++it)
			{
				cout << left << setw(5) << (*it)->getID() << setw(10) << (*it)->getFile() << setw(10) << (*it)->getMem() << setw(5) 
						 << (*it)->getAct() << setw(9) << (*it)->getFileLen() << setw(11) << (*it)->getTotalExecTime() << setw(9) 
						 << (*it)->getAvgCPUBurst() << setw(5) << (*it)->getCylinder();

				vector<Segment*> segmentTable = (*it)->segTable;

				for(unsigned int j = 0; j<segmentTable.size();  ++j )
				{
                                                ///////////////////////////////////////////////
                                                //SEGMENTATION FAULT IN BELOW COUT STATEMENT
                                                ///////////////////////////////////////////////
						cout << left << '(' << segmentTable[j]->base_ << ", " << segmentTable[j]->limit_ << ") ";

					if(j==1)
						cout << endl << setw(64) << "" ;

				}

				cout << endl;
			}
		}
	}


}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
class PCB
{
	private:
	//Each time a PCB is created, a new unique PID is automatically generated.
	PID id_;

	//JOB_POOL = 0, TERMINATED = 4
	enum status {JOB_POOL, READY, RUNNING, WAITING, TERMINATED};
	status s;

	enum action {IDLE, READ, WRITE};
	action act;


	string file;
	vector<unsigned int> limitsTable;



        //////////////////////////////////////////////
        //SEGMENT TABLE ACCESSED ABOVE IS THE VECTOR BELOW
        //////////////////////////////////////////////
	vector<Segment*> segTable;


	unsigned int size_;

	unsigned int memLoca;
	unsigned int fileLen;

	//cylinder only used for disk
	unsigned int cylinder=0;
	unsigned int totalExecTime=0;
	unsigned int CPUBurstCount=0;
	double avgCPUBurst=0.0;

	public:

	PCB();	
	PCB(const PCB& p);
	PCB(PCB&& p);
	PCB(unsigned int stat);
	//no need to implement destructor since nothing is stored in the heap.
	//~PCB();

	unsigned int size() const;
	unsigned int getID() const;
	unsigned int getStat() const;
	unsigned int getCylinder() const;
	unsigned int getMem();
	unsigned int getFileLen();
	unsigned int getTotalExecTime();

	vector<Segment*>& getSegTable();


	void printSegTable();


	double getAvgCPUBurst();
	char getAct();
	
	string getActString();
	string getFile();


	void insertSegTable(Segment* s);

	void setSize(unsigned int s);
	void setStat(unsigned int stat);
	void setAct(unsigned int a);
	void setTotalExecTime(unsigned int t);
	void setFile(string f);
	void setMem(unsigned int m);
	void setFileLen(unsigned int fl);
	void setPID();
        void updateAvgCPUBurst();
	void updateCPUBurstCount();
	void setCylinder(unsigned int c);
	void addTime(unsigned int t);

	PCB& operator=(const PCB& p);
	PCB& operator=(PCB&& p);

	friend class mySystem;
	friend class memory;
	friend class scheduler;
	friend class devControl;
	friend class disk;
	friend ostream& operator<<(ostream& out_stream, const PCB& p);

};



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

//////////////////////////////////////////////
//POINTER TO BELOW OBJECT IS DEREFERENCED
//////////////////////////////////////////////
class Segment
{
	private:

	bool valid_ = false;
	bool hole_ = true;

	unsigned int pid_;
	unsigned int base_;
	unsigned int limit_;

	public:

	Segment();
	Segment(const Segment& s);
	Segment(Segment&& s);
	Segment(unsigned int b, unsigned int l);
	Segment(unsigned int pid, unsigned int b, unsigned int l);

	unsigned int base();
	unsigned int limit();
	unsigned int pid();

	bool isHole() const;

	void fill();
	void free();
	void setBase(unsigned int b);
	void setLimit(unsigned int l);
	Segment merge(Segment s);

	Segment& operator=(const Segment& s);
	Segment& operator=(Segment&& s);


	friend class mySystem;
	friend ostream& operator<<(ostream& out_stream, const Segment& s);

};
Last edited on
Hi,

Are you sure everything is initialised? Look at the code with a debugger to see that is actually happening. :+)

What does the code that calls a segment constructor look like? I trying to imagine an orderly system whereby everything is initialised, then a coherent way of accessing and processing the data. At the moment, I don't get that feeling reading your code.

In my mind, you have too much happening in the void mySystem::snapshotDisk() function. Consider splitting it by making some private functions if you need to. Functions should do one conceptual thing.

Also, you have a lot of friend classes, effectively sharing the data between all the classes: doesn't sound good. Consider using the interface of each class to retrieve data, rather than sharing all of it.

Do you have a particular reason, like needing polymorphism, as to why you have so many pointers? C++11 has move semantics, so one can have a container of objects, rather than a container of pointers to objects.

There is also std::reference_wrapper , so you can have a container of references, if really needed - maybe not.

Hope this helps :+)
The first thing I would look at is: Where are the Segment objects stored that segTable is pointing to? Is it possible they're in a container that invalidates pointers to elements when it is resized?

Does PCB::insertSegTable validate pointers added?

But, mostly the first question. Where are these objects that are pointed to stored?
To be honest I am just rushing through the coding since it was just homework. I didn't have a lot of time to flesh everything out, but I intend to do that after the semester is over. I am just trying to get the basics done and submit a working program on time.

I didn't have a lot of time to debug yesterday, but I am currently trying to recover from a previous version of the program. The previous version there was no segmentation fault at all, and when I implemented something, which I don't remember what, it started giving segmentation faults.

Here are my Segment constructors:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
Segment::Segment()
{
	valid_ = false;
	pid_= 0;
	base_ = 0;
	limit_ = 0; 


}

Segment::Segment(const Segment& s)
{

	valid_ = s.valid_;
	pid_ = s.pid_;
	base_ = s.base_;
	limit_ = s.limit_; 
	hole_ = s.hole_;

}

Segment::Segment(Segment&& s)
{

	valid_ = std::move(s.valid_);
	pid_ = std::move(s.pid_);
	base_ = std::move(s.base_);
	limit_ = std::move(s.limit_); 
	hole_ = std::move(s.hole_);

}

Segment::Segment(unsigned int b, unsigned int l)
{
	base_ = b;
	limit_ = l;

}
Segment::Segment(unsigned int pid, unsigned int b, unsigned int l)
{
	pid_ = pid;
	base_ = b;
	limit_ = l;


}


Here is the call that stores what the vector<Segment*> segTable; points to:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
bool memory::allocate(PCB& p, unsigned int limit)
{
	list<Segment>::iterator memItr = mem_.begin();
	list<Segment>::iterator insertedSegItr;

	for(; memItr != mem_.end(); ++memItr)
	{
		if(memItr->isHole())
		{
			unsigned int sizeOfHole = memItr->limit();
			
			if(sizeOfHole >= limit)
			{
				unsigned int holeBase = memItr->base();
				Segment segToInsert(p.getID(), holeBase, limit);
			
				segToInsert.fill();
                                //////////////////////////////////
                                //MEM_ INSERTION
                                //////////////////////////////////      
				mem_.insert(memItr, segToInsert);
			

				insertedSegItr = memItr;
				--insertedSegItr;

				Segment* segPtr = &(*insertedSegItr);

                                //////////////////////////////////
                                //PCB'S SEGTABLE INSERTION
                                //////////////////////////////////      
				p.insertSegTable(segPtr);

				unsigned int newHoleLimit = memItr->limit() - limit;
				memItr->setLimit(newHoleLimit);
			
				
				if(newHoleLimit == 0)
				{
					mem_.erase(memItr);

				}
		
				else
				{
					memItr->setBase(holeBase+limit);

				}

				return true;
			}

		}

	}

	return false;

}


Here is the memory class header:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

class memory
{
	private:

	//contains filled and unfilled memory segments
        /////////////////////////////////////////////////////
        //THE SEGMENT POINTERS IN THE PCB VECTOR POINT TO SEGMENTS LIST IN MEM_
        /////////////////////////////////////////////////////
	list<Segment> mem_;

	unsigned int size_;
	unsigned int available_;
	unsigned int used_;


	public:
	memory();
	memory(unsigned int size);
	memory(list<Segment> m);


	bool allocate(PCB& p,  unsigned int limit);
	//void insert(list<Segment>::iterator hole, unsigned int limit)
	//uses first fit
	//fills process p's segTable as well
	//vertical view of memory: lower address on top, higher address on bottom
	void moveSegmentsUp();
	void mergeHoles();
	void free(PCB& p);
	void updateAccount();
	void printAccount();


	list<Segment>::iterator getFirstHole(list<Segment>& segList);

	unsigned int size();
	unsigned int available();
	unsigned int used();

	friend class mySystem;
	friend class scheduler;

	friend ostream& operator<<(ostream& out_stream, const memory& m);
};
Last edited on
In the following code fragment:
1
2
3
4
			        insertedSegItr = memItr;
				--insertedSegItr;

				Segment* segPtr = &(*insertedSegItr);


What do you accomplish with line 2?
Last edited on
@cire

I was trying to create a pointer to the newly inserted Segment object. So I needed access to it. Since list insertion inserts into position previous to current iterator, I needed another iterator to backtrack by one position after insertion to get the newly inserted Segment. Then I created a pointer to it and then inserted it into the PCB's vector<Segment*> segTable;.
I was trying to create a pointer to the newly inserted Segment object. So I needed access to it.

Aha. It's rare I find the need to use std::list. My thought process was that you might decrement an iterator past the begin iterator, but that checks out.

Here's what I think is happening. You "erase" a Segment (see line 40 in memory::allocate) which is pointed to by pointer contained in your vector, and then you try to dereference that pointer to the no longer existing Segment.
Here's what I think is happening. You "erase" a Segment (see line 40 in memory::allocate) which is pointed to by pointer contained in your vector, and then you try to dereference that pointer to the no longer existing Segment.


I don't think that is the error. memItr always points to a "hole" or an empty segment that doesn't belong to any PCB. The code never inserts a hole into vector<Segment*> segTable;. Unless it is somehow possible I still did it?
Unless it is somehow possible I still did it?

I don't see anything that would prevent it. Your Segment objects are stored in the same list, and from your class definition, the hole_ member will be set to true in the Segment added to the list.

I don't see anything that would prevent it. Your Segment objects are stored in the same list, and from your class definition, the hole_ member will be set to true in the Segment added to the list.


Oh, right, segToInsert.fill(); "fills" the hole and sets hole_ to false.
Last edited on
Then it seems I've reached the limit of my look-it-over-debugging given the code you've supplied. Using a debugger or instrumenting the code to log what's happening during execution would probably be a good next step for you.
Well it turns out Segment* inside vector<Segment*> segTable; is invalidated and recreated with different addresses after the PCB went out of scope. So I guess I have to dynamically allocate PCB object so this doesn't happen.
Last edited on
That would do it.
Topic archived. No new replies allowed.