4

It seems to me that this is how memory works in C++:

If you use new then you are asking the compiler's implementation to give you some memory (any memory) from the heap.

If you use the placement new syntax, the you are asking to re-allocate a specific memory location that you already know the address of (let's just assume it is also from the heap) which presumably was also originally allocated from the new operator at some point.

My question is this:

Is there anyway to know which memory locations are available to your program a priori (i.e. without re-allocating memory from the heap that was already given to you by the new operator)?

Is the memory in the heap contiguous? If so, can you find out where it starts and where it ends?

p.s. Just trying to get as close to the metal as possible as fast as possible...

Jimmy
  • 4,419
  • 6
  • 21
  • 30

4 Answers4

5

Not in any portable way. Modern operating systems tend to use paging (aka virtual memory) anyway, so that the amount of memory available is not a question that can be easily answered.

There is no requirement for the memory in the heap to be contiguous, if you need that you are going to have to write your own heap, which isn't so hard to do.

john
  • 85,011
  • 4
  • 57
  • 81
  • So, if you make your own heap, then you just call `new` for the total amount of memory that you are gonna need? – Jimmy Aug 09 '11 at 06:02
  • Yes you can do that, or you could just declare a very big array (if the amount of memory you need is fixed). – john Aug 09 '11 at 06:06
  • 1
    @Jimmy Yes, or you use one of the operating system's functions for getting large, contiguous blocks of address space. That's `VirtualAlloc()` in Windows, for example. – Crashworks Aug 09 '11 at 06:08
  • @john Declaring a really big array won't always work if that array is a local variable, because then the array will be allocated from the stack and you'll get... well, a Stack Overflow for arrays beyond a certain size. ( http://stackoverflow.com/questions/571945/getting-a-stack-overflow-exception-when-declaring-a-large-array ) – Crashworks Aug 09 '11 at 06:10
  • @Jimmy: typically you'd get to a lower level than that, ie rewrite your own implementation of `malloc` and friends, which are (typically) used by `new` under the covers. – Matthieu M. Aug 09 '11 at 06:16
  • @Crashworks: Well I was thinking that the array should be global, perhaps I should have made that clear. In any case it's not likely to be something Jimmy wants. Using new or something O/S specific is likely to be the right way. – john Aug 09 '11 at 06:22
2

The memory available to your program "a priori" contains the variables you have defined. The compiler has calculated exactly how much the program needs. There is nothing "extra" you can use for something else.

New objects you need to create dynamically are allocated from the free store (aka heap), possibly by using new but more often by using containers from the library like std::vector.

The language standard says nothing about how this works in any detail, just how it can be used.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
1

It is very difficult question. In modern operating system there are such subsystem as memory manager. When your program executes new operator, there are two options:

  • if there is enough memory available to program, you get pointer to memory in your program's heap
  • if there isn't enough memory, execution is given to memory manager of operating system and it decides what to do: give more memory to your program (let's say that it will resize your heap) or refuse and throw exception.

Is there anyway to know which memory locations are available to your program a priori (i.e. without re-allocating memory from the heap that was already given to you by the new operator)?

I want to emphasize that it depends on version of OS and on environment.

Is the memory in the heap contiguous?

No, it may be non-contiguous.

George Gaál
  • 1,216
  • 10
  • 21
1

The contiguity of addresses received from successive calls to new or malloc() isn't defined. The C runtime and operating system are free to return pointers willy-nilly all over the address space from successive news. (And in fact, it's likely to do so, since good allocators draw from different pools depending on the size of the allocation to reduce fragmentation, and those pools will be in different pages.)

However, bytes within a single allocation in new are guaranteed to be contiguous, so if you do

int *foo = new int[1024 * 1024] 

you'll get a million contiguous words.

If you really need a large, contiguous allocation, you'll probably need to use operating-system-specific functions to do so (unless someone has hidden this behind some Boost library I'm unaware of). On Windows, VirtualAlloc(). On POSIX, mmap().

Crashworks
  • 40,496
  • 12
  • 101
  • 170