Access Violation Writing Location - Linked Lists

I've been filling in bits and pieces of this code, and the part I'm having difficulty with is the List::insert() function in List.cpp.

When I try to do anything with headByName or headByRating I get
"Unhandled exception at 0x00412f2c in lab1.exe: 0xC0000005: Access violation writing location 0x00000004."

What am I not setting up right? I'm not allowed to change the header files for this assignment so I have to focus on the cpp files. I've done something to break it.

Any help would be very appreciated.



List.cpp (this is the one I'm working on, the other files are to look at if you need more clarification)
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
#include "memoryleakdetect.h"		// this must be the first #include in each of your .cpp files
#include <iostream>
#include "list.h"
//#include <cassert>


List::List() :
	headByName(NULL), 
	headByRating(NULL)
{
}

List::~List()
{
	Node	*node(headByName);
	Node	*nextNode;

	while(node)
	{
		nextNode = node->nextByName;
		delete node;
		node = nextNode;
	}
}

List::Node::Node(const Winery& winery) :
	nextByName(NULL),
	nextByRating(NULL),
	item(winery)
{
}


void List::displayByName(ostream& out) const
{
	Winery::displayColumnHeadings(out);
	// more code
}

void List::displayByRating(ostream& out) const
{
	Winery::displayColumnHeadings(out);
	// more code
}

void List::insert(const Winery& winery)
{
	Node	*newNode(new Node(winery));
	Node	*curr(headByName);

//it breaks here//////////////////////////////////////////////////////////
	if(!headByName) //also tried (headByName != NULL)
		headByName->item = newNode->item;
	
        //I haven't managed to move on to this part.
        //else
	//{
		//while(curr->nextByName)
		//{
			//curr = curr->nextByName;
		//}
		//curr->nextByName = newNode;
	//}


}

Winery * const List::find(const char * const name) const
{
	// your code here, return the appropriate value
	return 0;
}

bool List::remove(const char * const name)
{
	// your code here, return the appropriate value
	return false;
}



List.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
// make NO CHANGES to this file

#pragma once				// include this .h file file only once

#include <ostream>
#include "winery.h"

using namespace std;

class List
{
public:
	List(void);				// constructor
	virtual ~List(void);	// destructor

	// Print out the wineries in alphabetical order by name,
	// by calling winery's operator<< for each winery.
	void displayByName(ostream& out) const;

	// Print out the wineries from highest to lowest rating,
	// by calling winery's operator<< for each winery.
	void displayByRating(ostream& out) const;

	// Insert a winery into both the names and ratings threads.
	// The names thread should be in alphabetical order by name.
	// The ratings thread should be in order from highest rating
	// to lowest rating.
	void insert(const Winery& winery);

	// Return a const pointer to the winery instance it finds in
	// the list, or 0 if it didn't find a winery with that name.
	// Because the pointer is declared const, there is no danger
	// that find's caller will be able to use the returned pointer
	// to change the instance of winery.
	Winery * const find(const char * const name) const;

	// Remove the winery with the specified name from both the name
	// thread and the ratings thread. Returns true if it found and
	// removed the winery, false if it did not find the winery.
	bool remove(const char * const name);

private:
	// defines each node in the doubly-threaded linked list.
	struct Node
	{
		Node(const Winery& winery);		// constructor
		Winery item;					// an instance of winery
										// (NOT a pointer to an instance)
		Node *nextByName;				// next node in the name thread
		Node *nextByRating;				// next node in the rating thread
	};

	Node *headByName;					// first node in the name thread
	Node *headByRating;					// first node in the rating thread
};


Winery.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
#include "memoryleakdetect.h"		// this must be the first #include in each of your .cpp files
#include "winery.h"
#include<iomanip>
#include<iostream>

using namespace std;

// change the value of this variable to be your own name instead of "I. Forgot"
const char	Winery::YOUR_NAME[] = "Stephanie Johnson";

Winery::Winery(const char * const name, const char * const location, const int acres, const int rating) :
	name(NULL),
	location(NULL),
	acres(acres),
	rating(rating)
{
	if(this->name)
		delete [] this->name;
	this->name = new char[strlen(name)+1];
	strcpy(this->name, name);
	
	if(this->location)
		delete [] this->location;
	this->location = new char[strlen(location)+1];
	strcpy(this->location, location);
}

Winery::~Winery()
{
	if(name)
		delete[] name;

	if(location)
		delete[] location;
}

void Winery::displayColumnHeadings(ostream& out)
{
	cout << "name" << setw (26) << "location" << setw (18) << "acres" << setw (7) << "rating" << endl;
	cout << "----" << setw (26) << "--------" << setw (18) << "-----" << setw (7) << "------" << endl;
	// print out column headings for lists of wineries, as specified by lab1output.txt
}

ostream& operator<<(ostream& out, Winery *w)
{
	cout << w->name << setw (26) << w->location << setw (18) << w->acres << setw (7) << w->rating << endl;
	// print out a winery, as specified by lab1output.txt
	return out;
}


Winery.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
// make NO CHANGES to this file

#pragma once				// include this .h file file only once

#include <ostream>

class Winery
{
public:
	static const char	YOUR_NAME[];	// used for printing out programmer's name

	Winery(const char * const name, const char * const location, const int acres, const int rating);
	virtual ~Winery(void);

	// complete implementations for the following 4 functions, nothing needed in the .cpp file
	const char * const getName() const { return name; }
	const char * const getLocation() const { return location; }
	const int getAcres() const { return acres; }
	const int getRating() const { return rating; }

	// print out column headings for lists of wineries, as specified by lab1output.txt
	static void displayColumnHeadings(std::ostream& out);

	// print out a winery, as specified by lab1output.txt
	friend std::ostream& operator<<(std::ostream& out, Winery *w);

private:
	char	*name;
	char	*location;
	int		acres;
	int		rating;
};
closed account (zb0S216C)
You seem to be using a lot of C-style strings. The STL std::string will reduce the codes complexity. It'll also mean avoiding direct confrontation with pointers since std::string handles them internally.

Access violations are caused by dereferencing a null pointer. Before using a pointer, check for null before using it.

Wazzak
Last edited on
Turns out I was constructing Node all wrong. I had to add the pieces of the Winery->item to it as well, and that solved my problem.

I also changed headByName->item = newNode->item to headByName = newNode.

x_x

Thanks for responding to my post.
Topic archived. No new replies allowed.