As a Master's project, I am designing a simple operating system. It is being designed to run in 16-bit Real Mode on an x86 architecture. Ideally, I would like to develop this OS in C++, and only using assembly where necessary. Thus far, I have a boot loader written in assembly, that loads a kernel that is a mix of C++ and asm. My question is in regards to using C++. As of now, it has compiled and can run, but I have not used any dynamic memory allocation.

If I were using C, it would make sense to write malloc functions that would handle memory allocation, but in C++ the new keyword is used. So...

How does 'new' work behind the scenes to allocate memory, and how would I go about handling this?

And as a corollary...

Does it make sense to try to use C++ to take advantage of its higher level abstactions? Or would it be more of a headache to use it and should I stick with C?

Please provide rationale if you believe that C++ would not be a good choice.

4 Answers 4


The new keyword hands off the actual allocation to operator new, which behaves rather similar to malloc: it gets memory from somewhere. The compiler will then do all the constructor magic. Therefore, the C++ compiler will expect the C++ runtime lib (or your code) to provide an implementation of operator new.

It certainly makes sense to use C++ for certain abstractions. There's no reason why an OS should roll its own std::list<>. Exceptions are far more troublesome. In between there's a gradient from useful to useless stuff. std::complex ? It works perfectly, but why would you need it?


Many of the advantages of C++ over C have nothing to do with runtime support, and in those cases there's really no difference between code written in C and code written in C++. Templates, for example, don't do anything at runtime. They do nothing you couldn't do with a lot of extra typing. C++ is a very reasonable language to write operating systems in, since it provides low-level access when you need it, combined with higher-level abstractions than C when you don't need to focus on the bit-twiddling.

new does two things: it gets memory from somewhere, and it runs any necessary constructors. In getting the memory, it's no different from malloc.


Perhaps it would be reasonable to give a rough idea of the code that's normally generated for a new expression. It's generated by the compiler, but if you were implementing it as a function, it would look something like this:

template <class T>
T *new_object() { 
    void *raw_data = ::operator new(sizeof(T));
    return new(raw_data) T;

If you care about how new works, the (nearly) inevitable follow-up is how delete works:

template <class T>
void delete_object(T const *object) { 
    ::operator delete(object);

As others have already pointed out, ::operator new and ::operator delete are pretty basic memory allocators. For example, on a Unix-like system they'd probably call something like brk or sbrk to allocate large chunks of memory, and then hand out smaller chunks from those big blocks. In your own OS, you still probably want some sort of analog to sbrk and such -- something that starts with essentially all memory as "free", and allocates pieces of memory as needed. Given that you're working in real mode, that'll probably be fairly simple -- given the small amount of memory available, a practical design nearly needs to emphasize small size over elaborate algorithms.


Most operating systems are written in C I think. On the other hand it's a master's project so do something different and interesting.

  • 1
    Most large operating systems were initially written before C++ was available. That limited the choice. :-)
    – Bo Persson
    Commented May 23, 2011 at 17:34
  • 2
    sometimes I think downvotes are contagious.
    – Kevin
    Commented May 23, 2011 at 21:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.