Hi everyone,

For practice I am trying to code a simplified version of the template "std::list" but have come accross the LNK1120 + LNK2001 errors.

After looking in Visual Studio's documentation and some investigation, it seems the two most common causes are: 1) invalid calls in the code to things which don't exist, or 2) invalid project settings.

I can't seem to find any of these two problems in my code/project. On the other hand, I have also heard that these errors may be the result of some limitation in C++ where one template cannot call another one defined outside the calling header file, but I'm not sure about this last one.

In any case, I would really appreciate if someone could take a look at the following code and give me a hand. Thanks!

#ifndef LINKEDLIST_H
#define LINKEDLIST_H

#include <iostream>
#include <string>
#include "Linked Node 13_9_1.h"

using namespace std;

template <typename T>
class LinkedList
{
public:
	LinkedList();
	~LinkedList();
	LinkedList(const LinkedList& rhs);

	void append(T copieddata);
	void printlist();
	void destroy();

private:
	LinkedNode* mFirst;
	LinkedNode* mLast;
};

template <typename T>
LinkedList<T>::LinkedList()
{
	mFirst = 0;
	mLast= 0;
}

template <typename T>
LinkedList<T>::~LinkedList()
{
	destroy();
}

template <typename T>
void LinkedList<T>::destroy()
{
	if (mFirst != 0 )
	{
		LinkedNode<T>* current = mFirst;
		while ( current != 0 )
		{
			LinkedNode<T>* oldnode = current;
			current = current->next;
			delete oldnode;
			oldnode = 0;
		}
	}
}

template <typename T>
void LinkedList<T>::printlist()
{
		LinkedNode<T>* current = mFirst;
		while ( current != 0 )
		{
			cout << current->data << " ";
			current = current->next;
		}
}

template <typename T>
void LinkedList<T>::append(T copieddata)
{
	LinkedNode<T>* newNode = new LinkedNode<T>;
	newNode->data = copieddata;
	if ( mFirst == 0 )
	{	
		mFirst = newNode;		mLast = newNode;
		newNode->next = 0;		newNode->prev = 0;
	}
	else 
	{	
		newNode->prev = mLast;	mLast = newNode;
		newNode->next = 0;		newNode->prev->next = newNode;
	}
}

template <typename T>
LinkedList<T>::(const LinkedList& rhs)
{
	if ( rhs.mFirst != 0)
	{
		append(rhs.mFirst->data);
		LinkedNode<T>* index = rhs.mFirst->next;
		while ( index != 0)
		{
			append(index->data);
			index = index->next;
		}
	}
}
		
#endif // LINKEDLIST_H

Dani AI

Generated

— good debugging so far, and was right to flag the uninitialised pointers. The crash you see is a classic sign of heap corruption / double-delete caused by incorrect ownership or bad pointer state during copy/destruction. There are three concrete things to check and fix first: the copy-constructor definition, the node pointer types in the class, and the order/logic used when linking a new node.

Make sure the copy constructor is actually defined as a constructor (not a malformed function). It must initialize the target list to empty before calling append (best done in the member-initializer list), then walk the source list and append each element. Also ensure the private members use the templated node type (LinkedNode<T>* mFirst; LinkedNode<T>* mLast;) and that LinkedNode itself does not delete next or prev in its destructor (that would cause cascading double-deletes).

A minimal, safer pattern (illustrative) is:

template<typename T>
LinkedList<T>::LinkedList(const LinkedList& rhs)
  : mFirst(0), mLast(0)
{
  for (LinkedNode<T>* p = rhs.mFirst; p; p = p->next)
    append(p->data);
}

And make append robust: set newNode->next/prev explicitly, update the old mLast->next only if mLast exists, otherwise set mFirst. After destroy() clear mFirst/mLast to 0. Finally, implement the Rule of Three (copy ctor, assignment operator, destructor) so ownership is consistent.

If the bug persists, run under the VS debug heap: enable break-on-allocation with _CrtSetBreakAlloc, turn on full page heap / Application Verifier, or step with break-on-exception to see whether the heap gets corrupted during append or destroy. Those traces usually reveal whether the problem is a bad pointer, an incorrect node type, or an extra delete.

Recommended Answers

All 5 Replies

I seemed to have figured it out, C++ doesn't seem to like compiling header files alone (at least in terms of templates perhaps). I implemented a test source file with it and now it compiles fine.

Now, however, I have another problem (of course!): I run accross the following assertion failure after running the program in debug :

_BLOCK_TYPE_IS_VALID(pHead -> NBlockUse)

Although my test .cpp isn't shown here, in it I simply instantiate an object of LinkedList with the default constructor (which works fine).

On the other hand, I then instantiate another object using the class's copy constructor and it creates this error, any ideas?

Thanks to all,
Ivan

> On the other hand, I then instantiate another object using the class's copy constructor and it creates this error, any ideas?
You don't initialise mFirst in the current object before trying to append.

You're absolutely right I forgot to initialize, thanks for the tip :) I added mFirst = 0 and mLast= 0. The error, however, still persists.

I read that this may have to do with trying to delete a dyn mem allocation that was already deleted, but I don't see any problem with my destroy() routine....

What T are you using as the type for your list?

If it's a class, and it lacks a copy constructor, then your internal assignments are broken (when you copy the data)

What T are you using as the type for your list?

If it's a class, and it lacks a copy constructor, then your internal assignments are broken (when you copy the data)

Very true, for now I just designed the class to take simple types (i.e. chars, ints, floats....). Here's the source file for testing the template:

// TEST program for "Linked Node" & "Linked List"

#include <iostream>
#include <string>
#include "Linked List 13_9_1.h"

using namespace std;

int main()
{
	cout << "Creating a linked list of INTs with 5 elements:\n";
	LinkedList<int> tList;

	tList.append(3);
	tList.append(5);
	tList.append(7);
	tList.append(9);
	tList.append(11);
	tList.append(13);

	cout << "\nOutputting list: ";
	tList.printlist();

	cout << "\nCreating new list based on old list:\n";
	LinkedList<int> newList(tList);
	cout << "\nOutputting list: ";
	newList.printlist();
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.