delete error:acces violation
Mar 12, 2012 at 3:17pm UTC
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
Mar 12, 2012 at 3:34pm UTC
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 Mar 12, 2012 at 3:35pm UTC
Mar 12, 2012 at 3:37pm UTC
¿when do you ever put something in Item::_dlist ?
DList* my_list = new DList;
instead do DList my_list;
Mar 12, 2012 at 3:42pm UTC
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.
Mar 12, 2012 at 5:38pm UTC
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 Mar 12, 2012 at 5:46pm UTC
Mar 13, 2012 at 6:36pm UTC
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
//
//////
Mar 13, 2012 at 10:27pm UTC
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 Mar 13, 2012 at 10:30pm UTC
Topic archived. No new replies allowed.