PPP2 Chapter 17 Exercise 11

Pages: 1... 13141516
I think I should scrap the find_if_myth() function and take a different approach.

Pseudocode:
1
2
3
4
5
6
7
8
9
pass in all three lists plus source list into function
while the next pointer of the current node is not NULL, go to the tail of list and check myth strings of nodes
if myth == "Norse"
    insert into Norse list
else if myth == "Greek"
    insert into Greek list
else if myth == "Japanese"
    insert into Japanese list
keep traversing source list backwards through loop
Last edited on
That didn't work. I changed it to this:
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
void move_nodes(Link *dest_list, Link *source_list, const std::string &myth)
{
	Link *trav = source_list;
	while (trav->next())
	{
		trav = trav->next();
	}

	while (trav->previous())
	{
		if (trav->god().m_myth == myth)
		{
			trav->erase();
			if (trav->god().m_name != dest_list->god().m_name)
			{
				dest_list = dest_list->add_ordered(trav);
			}
		}
		if (trav->previous())
		{
			trav = trav->previous();
		}
		else
		{
			break;
		}
	}
}
Without the if (trav->previous()) check, it keeps touching a NULL previous pointer and crashing. So that's why that's there.

Anyway, I really can't see anything in my debugger aside from the value of _Right_size in the file xstring.h. So I can't tell what's going in my actual code file. I'm lost.
Last edited on
Have you even tried to look into any tutorials on how to use your debugger?

Start here: https://blogs.msdn.microsoft.com/vcblog/2017/06/23/c-tutorial-debugging-overview/

Don't forget to follow some of the links to more advanced information like:

https://docs.microsoft.com/en-us/visualstudio/debugger/debugger-feature-tour

and:

https://blogs.msdn.microsoft.com/vcblog/2017/04/10/c-debugging-and-diagnostics/

and:

https://blogs.msdn.microsoft.com/vcblog/2017/04/10/c-debugging-and-diagnostics/#datainspection

And there are so many other tutorials available for this Debugger that not knowing how to use your debugger should not be an excuse. You need to learn to properly use your tools. You say you want to become a programmer, so get to work.

I think my problem is something else concerning the debugging right now. I'm looking at my call stack, and I see these items:
1. file xstring, line 2186 in function _Construct_lv_contents(): const size_type _Right_size = _Right_data._Mysize;. The function itself is:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void _Construct_lv_contents(const basic_string& _Right)
		{	// assign by copying data stored in _Right
			// pre: this != &_Right
			// pre: *this owns no memory, iterators orphaned (note: _Buf/_Ptr/_Mysize/_Myres may be garbage init)
		auto& _My_data = this->_Get_data();
		auto& _Right_data = _Right._Get_data();
		const size_type _Right_size = _Right_data._Mysize;
		const _Elem * const _Right_ptr = _Right_data._Myptr();
		if (_Right_size < this->_BUF_SIZE)
			{   // stay small, don't allocate
			_Traits::copy(_My_data._Bx._Buf, _Right_ptr, this->_BUF_SIZE);
			_My_data._Mysize = _Right_size;
			_My_data._Myres = this->_BUF_SIZE - 1;
			return;
			}

		auto& _Al = this->_Getal();
		const size_type _New_capacity = _Min_value(_Right_size | this->_ALLOC_MASK, max_size());
		const pointer _New_array = _Al.allocate(_New_capacity + 1); // throws
		_Alty_traits::construct(_Al, _STD addressof(_My_data._Bx._Ptr), _New_array);
		_Traits::copy(_Unfancy(_New_array), _Right_ptr, _Right_size + 1);
		_My_data._Mysize = _Right_size;
		_My_data._Myres = _New_capacity;
		}

2. line 1926 in the same file, which is the last line here:
1
2
3
4
5
basic_string(const basic_string& _Right)
		: _Mybase(_Alty_traits::select_on_container_copy_construction(_Right._Getal()))
		{	// construct by copying _Right
		_Construct_lv_contents(_Right);
		}

3. line 15 in my own file, which consists of the initializers for the God struct:
: m_name{ name }, m_myth{ myth }, m_vehicle{ vehicle }, m_weapon{ weapon } { }

4. line 60 in my own file, in main where I try to initialize the gods list with Odin.

What I gather from all that is that there's a problem on line 60 when it tries to call the God struct constructor, in trying to call the initializers for the struct's members in particular. But what I don't understand is what's going on there. Like, if there's a problem with the string values I'm trying to use initialize those members, which does seem to be the problem, then what exactly is the problem and how do I fix it?

So I think my problem right isn't that I don't understand how to use to my debugger, but more that I don't understand how to interpret what I'm seeing in it. Those are two different things, aren't they? Also, I think I may have figured out what you meant by "stack trace". Were you talking about the call stack?

Another problem I'm facing is that it seems like VS can't download external source code. All I see is a screen saying "Source Not Found". I've asked about that on MSDN. Hopefully I'll get a good answer soon.

For reference, here's the Gist link for my code (updated): https://gist.github.com/DragonOsman/c08e31b18921762fb8b156ba665dce39

Oh and, before I forget, I did add the size_type constant _Right_size to the Watch. It says its value is 3435973836. But what does that actually mean? Is there a string in the God struct initializers that's too big?
Last edited on
What's the error message? My guess would be "illegal access reading location xxx". Am I right? What's in the xxx?
There's no error message. It's just showing me the size_type constant. The problem is somewhere around there and line 60 in main(), but I'm not sure what it is.
If the debugger stopped you there it should have shown you some kind of error message explaining why.
It didn't stop me on a breakpoint at that location because of an unhandled exception, though. And, again, look at what I said about my call stack.
So basically you're saying that you have no idea how to use the debugger, as I said in my last post. Did you even attempt to read and follow any of those tutorials?

Looking at some part of your compiler's standard implementation will probably not help you much, you really need to use the call stack to backtrack to your code, which is where the problem lies. About the only questionable thing you may glean out of your compiler's code is that the problem may (and I stress that word may) involve problems copying a std::string somewhere in your code.

By the way in that last code dump I don't see any attempt to actually debug the problem manually, which should be present since you don't know how to use the debugger.

I can't step through or step out anywhere with the way it is currently. I just go through those items I mentioned that I see in my call stack and then get to "External Code" which just gives me a "Source Not Found" screen. It's an infinite loop unless I exit the debugger. Don't you realize that I can't do anything right now? Please read my posts carefully.
Last edited on
It's an infinite loop unless I exit the debugger.

Why is this the first time you mentioned this when talking about your debugger?

Don't you realize that I can't do anything right now?

That's because you don't know how to use your debugger, read and do the tutorials I posted.

I can't step through or step out anywhere with the way it is currently.

Why can't you? Don't you know how to set a breakpoint? Set a breakpoint early in your code and single step through your code and then you should be able to see where you encounter the problem, at this stage don't step into any functions just single step through the code in main(). Once you know where the problem is occurring then re-run the program and step into your function where the problem is occurring, then single step through that function until you find out where the problem occurs, again at this stage don't step into any other function, just find out where the problem is in your code for this function.

Do you notice that big four letter word "your"? The problem will be in your code, not in the implementation's code!

Please read my posts carefully.

Maybe you need to be more careful to post all the relevant facts about the current problems.

And even if you refuse to use your debugger you should still have evidence of debugging statements scattered throughout your latest source code, but there is no such evidence apparent in your code.

There's no evidence of that because I'm trying to do it with the debugger. And I set breakboints in main where I call move_nodes(), but they aren't being hit. I'll have to set one a the point where main() starts, then. The line the call stack in the debugger is showing me is line 60 in main(). The problem should be around that area. But what's in the external code that I can't see? How do I get it to successfully download the missing code?

I do know how to set a breakpoint. It's just that I may have missed the fact that I should probably set one at the point where main() starts.

Edit: I set a breakpoint in main() and then stepped through the code, but I get stuck at the "Source Not Found" area again after the God object with the std::string values for initializing Odin were done. I have "this" set in my watch and I saw the string values in it in xtring header while stepping out (I was pressing F10 which is for stepping out, but I was still being shown the implementer's code. It's not my fault that it really seems to want to show me that code). Maybe I should I set a breakpoint in the God struct definition?
Last edited on
but I get stuck at the "Source Not Found" area

Did you try to Google something like: Visual C++ debugger "Source Not Found"?
I'll have to do that at some point. But no need right now because I think I got what's going on. After placing a breakpoint in main and taking out one that was there in xstring (accident, I guess), I was finally able to step through my code until I got to move_nodes. It got stuck in an infinite loop on Amaterasu and Bisamonten. I messed up when I had it look at both the head and the tail in find_if_myth().

I fixed that problem, but now it's not erasing any Japanese God nodes from the original list which is why it's stuck in an infinite loop. I just printed the jap_gods list and it's actually filled already. But at some point, for some reason, it started inserting the Japanese God nodes into both the Japanese list and the original list, which seems like the reason for the infinite loop. I don't know how this happened. This is the output:
norse_gods list:
{
Name: Baldr; Myth: Norse; Vehicle: A giant ship called Hringorni; Weapon: None
Name: Frejya; Myth: Norse; Vehicle: Chariot pulled by two cats; Weapon: Magic called seidr
Name: Odin; Myth: Norse; Vehicle: Eight-legged flying horse called Sleipnir; Weapon: Spear called Gungnir
Name: Thor; Myth: Norse; Vehicle: Chariot pulled by goats Tanngrisnir and Tanngnjostr; Weapon: Hammer called Mjolnir
}

greek_gods list:
{
Name: Ares; Myth: Greek; Vehicle: War chariot; Weapon: Sword and spear
Name: Athena; Myth: Greek; Vehicle: N/A; Weapon: Allowed to use Zeus's Thunderbolt and the Aegis
Name: Hera; Myth: Greek; Vehicle: A chariot drawn by peacocks; Weapon: Her intelligence
Name: Zeus; Myth: Greek; Vehicle: A chariot pulled by the four major winds shaped as horses; Weapon: Thunderbolt and the shield called Aegis
}

gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
}

jap_gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
}

jap_gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

jap_gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

jap_gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

jap_gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

jap_gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

jap_gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}
Okay, I had to a crazy little hack to kill the infinite loop after the Japanese Gods list was filled correctly. I took out the print_all() calls in the loops in main also all of the ones outside it except for the last three that show the results.

Here's the output:
norse_gods list:
{
Name: Baldr; Myth: Norse; Vehicle: A giant ship called Hringorni; Weapon: None
Name: Frejya; Myth: Norse; Vehicle: Chariot pulled by two cats; Weapon: Magic called seidr
Name: Odin; Myth: Norse; Vehicle: Eight-legged flying horse called Sleipnir; Weapon: Spear called Gungnir
Name: Thor; Myth: Norse; Vehicle: Chariot pulled by goats Tanngrisnir and Tanngnjostr; Weapon: Hammer called Mjolnir
}

greek_gods list:
{
Name: Ares; Myth: Greek; Vehicle: War chariot; Weapon: Sword and spear
Name: Athena; Myth: Greek; Vehicle: N/A; Weapon: Allowed to use Zeus's Thunderbolt and the Aegis
Name: Hera; Myth: Greek; Vehicle: A chariot drawn by peacocks; Weapon: Her intelligence
Name: Zeus; Myth: Greek; Vehicle: A chariot pulled by the four major winds shaped as horses; Weapon: Thunderbolt and the shield called Aegis
}

jap_gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}

gods list:
{
Name: Amaterasu; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Kusanagi, Jewel of Yasakani, Mirror of Yata
Name: Bishamonten; Myth: Japanese; Vehicle: N/A; Weapon: A spear
Name: Izanagi; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka (later given to Susanoo)
Name: Susanoo; Myth: Japanese; Vehicle: N/A; Weapon: Sword of Totsuka
}


And here's the Gist link again: https://gist.github.com/DragonOsman/c08e31b18921762fb8b156ba665dce39
Last edited on
Could someone help me get rid of the memory leaks now, please? I want to use unique_ptrs, but I got errors on my constructors when I tried to do it before. And the constructor I'm trying to call for std::unique_ptr<Link> is apparently a deleted function.
I tried it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
delete gods->find("Susanoo");
delete gods->find("Izanagi");
delete gods->find("Bishamonten");
delete gods->find("Amaterasu");
delete gods;
delete norse_gods->find("Thor");
delete norse_gods->find("Odin");
delete norse_gods->find("Frejya");
delete norse_gods->find("Baldr");
delete norse_gods;
delete greek_gods->find("Zeus");
delete greek_gods->find("Hera");
delete greek_gods->find("Athena");
delete greek_gods->find("Ares");
delete greek_gods;
delete jap_gods->find("Susanoo");
delete jap_gods->find("Izanagi");
delete jap_gods->find("Bishamonten");
delete jap_gods->find("Amaterasu");
delete jap_gods;


But I have a read access violation error being thrown on the delete gods->find("Izanagi"); line in main() and this part in find():
1
2
3
4
5
Link *tail = this;
while (tail->m_succ)
{
	tail = tail->m_succ;
}
, on the tail = tail->m_succ; line.
When you delete a node, are you properly removing it from the list, so that the other nodes' pointers are pointing to the right nodes?
An even better question is why does your gods Link contain the same gods as your jap gods Link? I would expect the gods Link, after glancing at your latest code dump, to have Odin, Zeus, and Amaterasu. And how many news do you have, and how many deletes doe your have? Oh and why are you trying to delete gods, norse_gods, greek_gods, and jap_gods?

But I have a read access violation error being thrown on the delete gods->find("Izanagi"); line in main()

What do you think this is telling you?

and this part in find():

What are the values of the variables at that point?

Last edited on
Pages: 1... 13141516