I coded everything so that this kind of syntax would be possible, but now, when I execute my program, I get the following error:
First-chance exception at 0x00DA6636 in Advanced Linked Lists.exe: 0xC0000005: Access violation reading location 0xFEEEFEEE.
Unhandled exception at 0x00DA6636 in Advanced Linked Lists.exe: 0xC0000005: Access violation reading location 0xFEEEFEEE.
I assume that a nullptr is being used at some point, but it's hard to wrap my head around my code currently and I would really like to move on with my project.
You did not provided copy constructor for your list.
That means when you do List<List<std::string>> words(5, List<std::string>(5, "Hello")); a temporary list is created (bold), gets copied by default copy constructor (shallow copy, that means pointers are copied but not data in them) and then temporary is destroyes. After that all pointers inside inner list are pointing to the freed memory. Which VS catches by deliberately setting freed memory for some specific value.
Should I add a copy constructor to my List class like so:
List(int length, T& fillWith);
Or do I have to do something else?
Edit: Apparently I have to do something else, because List(int length, T& fillWith); seems to deliver the same output.
Edit2: Now I removed the List(int length, T fillWith); constructor and the compiler says:
none of the 4 overloads could convert all the argument types
Edit3: I did some research into copy constructors and it seems that I am only aloud to pass in a reference of List? making the previous List(int length, T& fillWith); wrong?
Should I add a copy constructor to my List class like so:
Copy constructor has a specific purpose: it constructs a copy of another object. And it has specific signature:
1 2 3
class foo
{
foo(const foo& origin)
There is a Rule of Three: Copy constructor, Assigment operator, Destructor. If you have to provide your own implementation for one of them, you should implement others too. (C++11 add Move constructor and Move assigment to the list making it a Rule of Five)
So yes. You should implement Copy constructor and Assigment operator.
Wow, this project is becoming a huge learning experience for me. Thanks, it seems I'll have to do some more research on constructor types before I move on.
Let me explain.
Your temporary list holds a pointer "head". It points to some memory area A. Lets call that pointer temp@head
your real list holds head pointer too. It is currently pointing to the, say, null area. Lets call that pointer real@head
When you assign temp@head to real@head, both those pointers point to the same memoryA.
Then temporary list is destroyed and in deletes all memory it owns, including A. So now real@head points to deleted memory. And when you trying to access it: CRASH
I am totally lost right now.
I know generally what's causing the error, I just don't know how to fix it.
And I don't get why the copy constructor is being called in the first place if I type:
List<List<char>> words (5, List<char>(5, 'H'))
Shouldn't the constructor List(int length, T fillwith) be called and not the copy constructor?
Your constructor: List(int length, T fillWith);
Note thatit dies not take two ints and char. It takes int and T, which in your case is List<char>.
Before we can pass that T, we need to create it first. In your case constructor (int, char) is called. Now when we do have T, we need to pass it. That is where copy constructor is called.
Basically List<List<char>> words (5, List<char>(5, 'H')) is equal to:
1 2
List<char> temp(5, 'H');
List<List<char>> words (5, temp);
All five created sub lists are pointing to the same memory. It is completely possible that one of them wrecks it.
My problem now is that I don't know how ...
What do you need to copy list?
You need to copy all nodes preserving relationship between them. So for each node in origin list you append a copy of it to your list. Simple enough.
To do that you need to make Node properly copyable too. Well it is not that hard. You just need to copy data and set next to 0. Like that:
If you're using VC++, the value 0xCCCCCCCC is used to fill uninitialized memory allocated on the stack. So, you might look for a value you're using that you didn't initialize or assign any meaningful value (such as the head and tail values that you didn't set prior to calling append in your copy constructor.)
BTW: you can have both const and non-const versions of same function/operator. (That is how operator[] works for vector: you still can get value from const vector but cannot change it)
Thanks so much for sticking with me for over 5 hours MiiNiPaa. I've been working on this project for a few days now and it's been seriously frustrating 80% of the time. Well, it works now and I believe it should be possible for me to finish alone. Thanks again and good day.