views:

122

answers:

3

I'm just playing around with a grub-bootable C++ kernel in visual studio 2010.

I've gotten to the point where I have new and delete written and things such as dynamically allocated arrays work. I can use STL lists, for example. I can even sort them, after I wrote a memcpy routine. The problem is when I use the std::vector type. Simply constructing the vector sends the kernel off into la la land.

Obviously I'm missing a function implementation of some kind, but I looked through STL searching for it and came up empty-handed. It fails at the push_back:

vector<int> v;
v.push_back(1);

and disappears into the ether.

Any guesses as to what I'm missing?

Edit yes it's vector of int. Sorry for the confusion. Not only that, but it's not the constructor it fails on, it's a call to push_back.

+5  A: 

Stab in the dark: do you have new[] and delete[] implemented? A list will create one item at a time with new while a vector will likely allocate larger blocks of memory with new[].

John Kugelman
That just might be it. I've looked at allocators too, but I think you've probably got this one. Let me try it.
jjacksonRIAB
Nope, I implemented new[] and delete[] and those don't get called on the push_back.
jjacksonRIAB
@jjacksonRIAB Could it be calling realloc?What happens when you do a resize() or a reserve() ?
George
Keep in mind that just because `push_back` fails doesn't mean that's where the problem is. It could be that the vector was incorrectly constructed. I would expect the constructor to reserve a block of memory which explains why `push_back` doesn't allocate any memory.
John Kugelman
@George, realloc is in but it isn't being called during resize or reserve. Thanks though, my net is widened as to where I should be looking for this missing function call.@John: yeah your explanation makes sense. I'll continue looking into the vector code for what call I'm missing. I have new, delete, new[], delete[], malloc, free, realloc, memcpy, memmove. I don't know what it's tripping over, it's just trying to jump to a target that isn't there. Both resize and push_back fail. push_back works on a list just fine though.
jjacksonRIAB
@jjacksonRIAB Another thought, what happens if you use std::vector<mySimpleStruct> instead? I'm wondering if there might be a template specialization for std::vector<int>. If there is, your problem might be specific to the specialized version.
George
@George: Aha! You're right. It's not doing it on a simple struct, or a simple struct with an int in it. Just int. And reserve also works on simple structs. I'll look for a specialization somewhere in the code for int and see how it differs.
jjacksonRIAB
@jjacksonRIAB: Glad I could help! Maybe I should post it as an answer instead of a comment next time :)
George
@George: Nevertheless, thanks for your patience. OS development is a very throw-at-the-wall-and-see-what-sticks kindof deal, at least until you get to the point where it can actually be debugged. You've helped narrow the problem down quite a bit. Thanks! :-)
jjacksonRIAB
+3  A: 

As per our discussion above, creating a

std::vector<mySimpleStruct> v;

instead of a

std::vector<int> v;

appears to work correctly. This must mean the problem is with something being done in the specialization of some functions for std::vector in your standard template library. I'm assuming you're familiar with template specialization already, but in case you're not:

http://www.parashift.com/c++-faq-lite/templates.html#faq-35.7

Also, once you've figured out where the real problem is, could you come back and post the answer here? You have me curious about where the real problem is now, plus the answer may be helpful to others trying to build their own OS kernels.

George
A: 

Do you use a custom allocator or a default one?

You might try using a custom one just to see what allocations vector peforms that might destroy your implementation of the memory manager (this is probably what actually fails).

And yes, please post back once you solve it - it helps all other OSdevers out there.

Berkus