delete error:acces violation

Hi guys,

I made a double linked list but the delete function and the x, destroy functions are giving me the acces violation error. I know this means im deleting something that isnt mine, but i cant figure it out.

main.cpp
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
//////////////////////////////////////////
// Task Double Linked List
// Name ______________ your name _________
//
// file main.cpp
//////////////////////////////////////////
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "dlist.h"
#include <cstdlib>
#include <iostream>




void main()
{
	DList* my_list = new DList;
	int id;
	// define your my_list here

	char command;
	do
	{
		printf("\n\nType command: ");
		scanf(" %c", &command);
		switch (command)
		{
		case 'a': 
			printf("Appending an item...\n\n");
			my_list-> append();
			break; // append
		case 'i': 
			printf("Inserting an item...\n\n");
			my_list-> insert();
			break; // insert				
		case 'd': 
			printf("which id would you like to delete??\n\n");
			scanf(" %i", &id);
			my_list->delete_item(id);
			//delete my_list;
			break; // delete
		case 'f': 
			printf("Which id would you like to put first??\n\n");
			scanf(" %i", &id);
			my_list->put_first(id);
			break; // put first
		case 'p': 
			my_list-> print();
			break; // print
		case 's': 
			my_list->sort();
			break; // sort
		case 'x': 
			my_list->destroy_list();
			break; // destroy list
		case 'q': 
			printf("-> Bye Bye!");
			exit(1); // quit
		default :
			printf("Command unknown!\n");
			break;
		}
	}
	while (command != 'q');

	printf("Bye bye!\n");
	// delete your my_list here
}



dlist.cpp
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
// Task Double Linked List
// Your name: ______________ your name _________________

#include <stdio.h>
#include "dlist.h"
#include <cstdlib>
#include <iostream>
//////
//
//  Function bodies of members of the Item class
//
//////

Item::Item()
{
	_id = -1;
	_dlist = NULL;// TODO: initialize member values here
}

Item::~Item()
{
	_dlist->unlink(this);
	// TODO: remove this item from the list it's in
}

// Body of the the Item::print member function
// note that the term 'virtual'does not appear here
void Item::print()
{

	printf(" -> Appended item id %i\n", _id );// of _dlist;

}

// TODO: Implement the other member function bodies below

//////
//
//  End of the Item class
//
//////

//////
//
//  Function bodies of members of the DList class
//
//////

DList::DList()
{
	_top_of_ring = NULL;
	_id_counter = 0;

}

DList::~DList()
{
	// destroy the list
	destroy_list();
}

void DList::destroy_list(void){
int i;
	for(i = _id_counter; i > 0 ; i-- ){
		delete find(i);
		print();
	}
}

void DList::print(void){
	int i = 0;	//TODO: Implement this function
	Item* _current_class = _top_of_ring->_next; 

	if(_id_counter == 0){
		printf("-> List contains no items");	
	}
	else{	
		printf("-> order %i",  (i+1) );	
		_current_class->_prev -> print();
		for(i=0; _current_class != _top_of_ring; i++){
			printf("-> order %i",  (i+2) );	
		
			_current_class -> print();
			_current_class = _current_class -> _next;
		}
	}
}

Item* DList::create(void){
	 
	return (new Item);

}

Item* DList::append(void){
	_id_counter++;
	if(_id_counter == 1){
		_top_of_ring = create();
		_top_of_ring->_next = _top_of_ring->_prev = _top_of_ring;
		_top_of_ring->_id = _id_counter;
	}
	else{
		Item* temp = _top_of_ring->_prev;
		_top_of_ring->_prev = create();
		_top_of_ring->_prev->_next = _top_of_ring;
		_top_of_ring->_prev->_prev =  temp;
		temp->_next = _top_of_ring->_prev;

		_top_of_ring->_prev->_id = _id_counter;
		
	}
	_top_of_ring->_prev-> print();

	return(_top_of_ring->_prev);
}

Item* DList::insert(void){
	_id_counter++;
	if(_id_counter == 1){
		_top_of_ring = create();
		_top_of_ring->_next = _top_of_ring->_prev = _top_of_ring;
		_top_of_ring->_id = _id_counter;
	}
	else{
		Item* temp = _top_of_ring->_prev;
		_top_of_ring->_prev = create();
		_top_of_ring->_prev->_next = _top_of_ring;
		_top_of_ring->_prev->_prev =  temp;
		temp->_next = _top_of_ring->_prev;
		_top_of_ring->_prev->_id = _id_counter;
		_top_of_ring = _top_of_ring->_prev;
	}
	_top_of_ring-> print();
	
	return(_top_of_ring->_prev);
}

Item* DList::find(int id){
	int i = 0;
	Item * found = NULL;
	Item * _current_class = _top_of_ring; 
	for(i =0; i < _id_counter; i++){
		if(id == _current_class->_id){
			found = _current_class;
			break;
		}
		_current_class = _current_class->_next;
	}

	//printf(" %i", _current_class->_id);
	return(found);
};

Item* DList::unlink( Item * ptr){
	Item* _current_class = ptr;
	
	_current_class->_next->_prev = _current_class->_prev;
	_current_class->_prev->_next = _current_class->_next;
	if( _current_class == _top_of_ring){
		_top_of_ring = _current_class->_next;
	}
	return(ptr);	
};

int DList::delete_item(int id){
	unlink (find(id));
	delete (find(id));
	
	return id;
};

int DList::put_first(int id){	
	if(find(id)!=NULL){
		unlink (find(id));

		Item* temp = _top_of_ring->_prev;
		_top_of_ring->_prev = create();
		_top_of_ring->_prev->_next = _top_of_ring;
		_top_of_ring->_prev->_prev =  temp;
		temp->_next = _top_of_ring->_prev;
		_top_of_ring = _top_of_ring->_prev;
	

	
		_top_of_ring->_id = id;
	}
	return 0;//wtf
}


void DList::sort(void){
	int id;
	for(id = _id_counter; id >0; id--){
		put_first(id);

	}
	

}
// TODO: Implement the other member function bodies below

//////
//
//  End of the DList class
//
//////


dlist.h
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
#ifndef _DLIST_H_INCLUDED
#define _DLIST_H_INCLUDED

// Taks Double Linked List
// Your name: ___________ your name _________________________
//
// The following declaration is necessary to be able
// to declare '_dlist' as a 'DList *' before the Class Dlist
// has actually been defined

class DList;


// The Item class
// This class will serve as a base class for ALL type of items
// that will ever be added to a DList.
// It defines basic functionality

class Item
{
public:
	// constructor
	
	//destructor definition
	// note: function bodies still have to be implemented!
	Item(void);
	~Item(void);

	virtual void print(); // why is this one declared as virtual ?? Think about it!!

	// define additional member function here

protected:
	int _id;	// The id of the item.

private:
	Item* _prev;
	Item* _next;
	DList* _dlist;
	friend class DList;
};

// The DList class
// This class defines basic functionality that one would
// expect from a double linked list.

class DList
{
public:
	DList(void);
	~DList(void);

	// define additional member function here
	void destroy_list();
	void print();
	virtual Item* create();
	virtual Item* append();
	virtual Item* insert();
	virtual Item* find(int id);
	Item* unlink(Item* ptr);
	int delete_item(int id);
	int put_first(int id);
	void sort(void);

private:
	Item* _top_of_ring;
	int _id_counter;
	
	//friend class Item;
};

#endif
You should eliminate the empty lines at the end of you code...

I know this means im deleting something that isnt mine
Not necessarily

On line 18 (dlist.cpp) you call unlinke() but at this point (the delete is already called) there shouldn't be any unlink action.

unlink() itself:
1
2
	_current_class->_next->_prev = _current_class->_prev;
	_current_class->_prev->_next = _current_class->_next;
Are you sure that '_current_class->_next' and '_current_class->_prev' are always valid? And _current_class?
Last edited on
¿when do you ever put something in Item::_dlist ?
DList* my_list = new DList; instead do DList my_list;
1
2
3
4
5
6
7
void DList::destroy_list(void){
int i;
	for(i = _id_counter; i > 0 ; i-- ){
		delete find(i);
		print();
	}
}

if 'find(i)' return NULL, you delete an object that not exist. The list is double linked too, use other solution :
1
2
3
4
5
6
7
8
9
10
11
12
void DList::destroy_list(void){
    Item *p=_top_of_ring;
    Item *t;
    if(p){
        do{
            t=p->_prev;
            delete p;
            p=t;
        }while(p != _top_of_ring;
        _top_of_ring=NULL;
    }
}

And then, take a look to this part:
1
2
3
4
5
Item::~Item()
{
	_dlist->unlink(this);
	// TODO: remove this item from the list it's in
}

Maybe this can cause the problem.
if 'find(i)' return NULL, you delete an object that not exist


Deleting a null pointer does what you expect: nothing. It is well defined.

1
2
3
4
5
6
int DList::delete_item(int id){
	unlink (find(id));
	delete (find(id));
	
	return id;
};


This bothers me. find() can return NULL. Unlink doesn't check to see if what it's fed is NULL and dereferences it. That's bad. Also, as Vin points out, Item unlinks itself on destruction so:

1
2
3
4
int DList::delete_item(int id){
	delete (find(id));
	return id;
}


should be all that you need for delete_item.

Actually, took a closer look at the item class. You have another problem there. The member _dlist is set to NULL, and nothing ever changes it. So, every time an Item is destructed it dereferences a null pointer. I think the simplest fix is to change your DList::create function to:

1
2
3
4
5
Item* DList::create(void){
	 Item * newItem = new Item ;
        newItem->_dlist = this ;
	return newItem;
}




Last edited on
That works like a charm.
Thanks very much!!!


Now im running into the same problem with a script a little different:s
I think its in my create again

ps i tried some things and im closer now than before
this code still gives the following errors:

1>d:\desktop\book.cpp(21): error C2040: 'ptr' : 'Person' differs in levels of indirection from 'Person *'
1>d:\desktop\book.cpp(21): error C2512: 'Person' : no appropriate default constructor available


book.cpp
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
// Task Double Linked List
// Your name: ______________ your name _________________

#include <stdio.h>
#include "book.h"
#include <cstdlib>
#include <iostream>

Book::Book()
{
}

Book::~Book()
{
}

Item* Book::create(void){
	char s[100];
	scanf(" %s", &s);
	Person* ptr = new Person(s);
	Person(ptr);

}


Person::Person(char * person_name)
{
	strcpy(_name, person_name);

}

Person::~Person()
{
}

void Person::print(void){
		printf(" '%s' (id %d)\n", _name, _id);
	}


book.h
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
#include "dlist.h"



class Book: public DList
{
public:
	Book(void);
	~Book(void);
	Item* create();


	
};

class Person: public Item{
public:
	Person(char * person_name);
	~Person(void);
	void print(void);


private:
	char _name[64];
	
	friend class Book;
};



main.cpp
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
//////////////////////////////////////////
// Task Double Linked List
// Name ______________ your name _________
//
// file main.cpp
//////////////////////////////////////////
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include "dlist.h"
#include <cstdlib>
#include <iostream>
#include "book.h"




void main()
{
	Book* lord_of_the_rings = new Book;
	int id;
	// define your my_list here

	char command;
	do
	{
		printf("\n\nType command: ");
		scanf(" %c", &command);
		switch (command)
		{
		case 'a': 
			printf("\n-> Type charter name: ");
			lord_of_the_rings-> append();
			break; // append
		case 'i': 
			printf("\n-> Type charter name: ");
			lord_of_the_rings-> insert();
			break; // insert				
		case 'd': 
			printf(" Enter item id: ");
			scanf(" %i", &id);
			lord_of_the_rings->delete_item(id);
			//delete my_list;
			break; // delete
		case 'f': 
			printf("Which id would you like to put first??\n\n");
			scanf(" %i", &id);
			lord_of_the_rings->put_first(id);
			break; // put first
		case 'p': 
			lord_of_the_rings-> print();
			break; // print
		case 's': 
			lord_of_the_rings->sort();
			break; // sort
		case 'x': 
			lord_of_the_rings->destroy_list();
			break; // destroy list
		case 'q': 
			printf("-> Bye Bye!");
			exit(1); // quit
		default :
			printf("Command unknown!\n");
			break;
		}
	}
	while (command != 'q');

	printf("Bye bye!\n");
	// delete your my_list here
}



DList.cpp
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
// Task Double Linked List
// Your name: ______________ your name _________________

#include <stdio.h>
#include "dlist.h"
#include <cstdlib>
#include <iostream>
//////
//
//  Function bodies of members of the Item class
//
//////

Item::Item()
{
	_id = -1;
	_dlist = NULL;// TODO: initialize member values here
}

Item::~Item()
{
	_dlist->unlink(this);
	// TODO: remove this item from the list it's in
}

// Body of the the Item::print member function
// note that the term 'virtual'does not appear here
void Item::print()
{

	printf(" -> Appended item id %i\n", _id );// of _dlist;

}

// TODO: Implement the other member function bodies below

//////
//
//  End of the Item class
//
//////

//////
//
//  Function bodies of members of the DList class
//
//////

DList::DList()
{
	_top_of_ring = NULL;
	_id_counter = 0;

}

DList::~DList()
{
	// destroy the list
	destroy_list();
}

void DList::destroy_list(void){
    Item *p=_top_of_ring;
    Item *t;
    if(p){
        while(p != _top_of_ring){
            t=p->_prev;
            delete p;
            p=t;
        }
        _top_of_ring=NULL;
		_id_counter = 0;
    }
}


void DList::print(void){
	int i = 0;	//TODO: Implement this function
	
	printf("%i", _id_counter);
	if(_id_counter == 0){
		printf("-> List contains no items");	
	}
	else{
		Item* _current_class = _top_of_ring->_next; 
		printf("-> order %i",  (i+1) );	
		_current_class->_prev -> print();
		for(i=0; _current_class != _top_of_ring; i++){
			printf("-> order %i",  (i+2) );	
		
			_current_class -> print();
			_current_class = _current_class -> _next;
		}
	}
}

Item* DList::create(void){
	 Item * newItem = new Item ;
     newItem->_dlist = this ;
	return newItem;
}



Item* DList::append(void){
	_id_counter++;
	if(_id_counter == 1){
		_top_of_ring = create();
		_top_of_ring->_next = _top_of_ring->_prev = _top_of_ring;
		_top_of_ring->_id = _id_counter;
	}
	else{
		Item* temp = _top_of_ring->_prev;
		_top_of_ring->_prev = create();
		_top_of_ring->_prev->_next = _top_of_ring;
		_top_of_ring->_prev->_prev =  temp;
		temp->_next = _top_of_ring->_prev;

		_top_of_ring->_prev->_id = _id_counter;
		
	}
	
	printf("-> Appended ");
	_top_of_ring->_prev-> print();
	return(_top_of_ring->_prev);
}

Item* DList::insert(void){
	_id_counter++;
	if(_id_counter == 1){
		_top_of_ring = create();
		_top_of_ring->_next = _top_of_ring->_prev = _top_of_ring;
		_top_of_ring->_id = _id_counter;
	}
	else{
		Item* temp = _top_of_ring->_prev;
		_top_of_ring->_prev = create();
		_top_of_ring->_prev->_next = _top_of_ring;
		_top_of_ring->_prev->_prev =  temp;
		temp->_next = _top_of_ring->_prev;
		_top_of_ring->_prev->_id = _id_counter;
		_top_of_ring = _top_of_ring->_prev;
	}
	
	printf("-> Inserted ");
	_top_of_ring-> print();
	
	return(_top_of_ring->_prev);
}

Item* DList::find(int id){
	int i = 0;
	Item * found = NULL;
	Item * _current_class = _top_of_ring; 
	for(i =0; i < _id_counter; i++){
		if(id == _current_class->_id){
			found = _current_class;
			printf(" %i", found);
			return(found);
		}
		_current_class = _current_class->_next;
	}

	//printf(" %i", _current_class->_id);
	
};

Item* DList::unlink( Item * ptr){
	Item* _current_class = ptr;
	
	_current_class->_next->_prev = _current_class->_prev;
	_current_class->_prev->_next = _current_class->_next;
	if( _current_class == _top_of_ring){
		_top_of_ring = _current_class->_next;
	}
	return(ptr);	
};


int DList::delete_item(int id){
	printf("-> Deleted item with id %i", id);
	delete (find(id));
	return id;
}



int DList::put_first(int id){	
	if(find(id)!=NULL){
		unlink (find(id));

		Item* temp = _top_of_ring->_prev;
		_top_of_ring->_prev = create();
		_top_of_ring->_prev->_next = _top_of_ring;
		_top_of_ring->_prev->_prev =  temp;
		temp->_next = _top_of_ring->_prev;
		_top_of_ring = _top_of_ring->_prev;
	

	
		_top_of_ring->_id = id;
	}
	return 0;//wtf
}


void DList::sort(void){
	int id;
	for(id = _id_counter; id >0; id--){
		put_first(id);

	}
	

}
// TODO: Implement the other member function bodies below

//////
//
//  End of the DList class
//
//////
1
2
3
4
5
6
7
Item* Book::create(void){
	char s[100];
	scanf(" %s", &s);
	Person* ptr = new Person(s);
	Person(ptr);

}


I suspect you meant to do:

1
2
3
4
5
Person* Book::create(){
	char s[100];
	scanf(" %s", &s);
	return new Person(s);
}


Conceptually, input shouldn't be done here. You can return the correct type here - google "covariant return types."

You were trying to instantiate a person with a pointer to Person as an argument to the constructor, which is what your compiler was complaining about.

Oh yes. ~Item() and ~Dlist() should be virtual.


Last edited on
Topic archived. No new replies allowed.