1

Is there a max limit to the number of bytes you can allocate to an array pointer?

For example if i use a size of 16000 then this works.

char* iobuffer=new char(16000);
iobuffer[15000]='a';

However

char* iobuffer=new char(160000);
iobuffer[150000]='a';

this does not.

It shouldn't be a memory issue so is there some internal restriction? After looking further it might be that the heap cannot store that much.

Jake
  • 2,877
  • 8
  • 43
  • 62

2 Answers2

11

You've actually got your allocation code wrong. You're using parenthesis, which provide an initializer for your newly allocated value. In other words, in both cases you have a single char allocated for use, initialized to 16000 and 160000 respectively. Use brackets to dynamically allocate an array.†

After that, you subscript (way) out of bounds, leading to undefined behavior. (Any subscript past zero in your case is undefined behavior; more generally, subscripting past array bounds is undefined behavior.)

To answer the question, there is no limit, language-wise. It depends on your running environment.


†Of course, you should never use new[]. Use std::vector instead.

Community
  • 1
  • 1
GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • Then why does the first case work? Surely 15000 is out of bounds for a size 1 array... –  Apr 08 '11 at 00:59
  • 4
    It doesn't "work". It's undefined behavior. You simply got lucky. (Or, one could argue unlucky as to you it seemed it was working) – Brian Roach Apr 08 '11 at 01:00
  • I bet if you turn on optimization (pass `-O2` to GCC), the first case won't work any more. `-O0` seems to give bad programming a lot of slack. – Seth Johnson Apr 08 '11 at 01:10
1

To answer your question, the limit is the largest block available on the heap. It's not a constant number, even throughout the execution of your program it changes.

That is why, you must always verify that the memory was allocated. After each new check the result for null pointer and catch exceptions, if those are enabled.

All that regardless of the mistakes in your code which were pointed out already, and the valid suggestion to use std::vector instead of directly allocating arrays.

littleadv
  • 20,100
  • 2
  • 36
  • 50
  • `new` will never return null in C++. – GManNickG Apr 08 '11 at 01:14
  • Except in some special cases like really old compilers and strange embedded environments, `operator new` will never return null unless you use `std::nothrow`. I hate seeing code cluttered with null checks that can never be triggered. -- http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.6 – Tim Sylvester Apr 08 '11 at 01:25
  • 1
    Well, forgive me for being used to some old compilers and embedded environments where we have exceptions disabled by default:-) Better safe than sorry, I say, but using `std::vector` instead solves the issue in a much better way anyway. – littleadv Apr 08 '11 at 01:27
  • 1
    What happens when `std::vector` can't allocate memory and exceptions are disabled? Do you get some "push back"? (sorry) But seriously, does it crash the app, or do you have to check that the size of the vector actually increased every time you add something to it? Both of those possibilities are just awful. – Tim Sylvester Apr 08 '11 at 02:10
  • @Tim, `std::vector` provides random access, but it doesn't provide contiguous memory, so it can allocate more than one single chunk, and hide it from you. If you're totally out of memory, well then the app will crash or do some other undefined stuff, and we have to live with the fact that sometimes the behavior is undefined. If we're in an environment which must be deterministic at all times, then yes - you must check (but you'd probably do it through the `allocator` optional parameter of the `std::vector`). – littleadv Apr 08 '11 at 02:19
  • 1
    @littleadv: `std::vector` guarantees a contiguous memory block just like any `new sometype[N]` returns. This allows you to, for example, pass `&(x[0])` to old C-style routines that want a pointer to allocated memory. http://www.parashift.com/c++-faq-lite/containers.html#faq-34.3 – Seth Johnson Apr 08 '11 at 02:59
  • @Seth thanks for the correction, but it doesn't really change the point. – littleadv Apr 08 '11 at 03:02
  • @littleadv: So on your platform, running out of memory is a crash? – GManNickG Apr 08 '11 at 03:09
  • @GMan On my platform running out of memory triggers a reboot (all the allocators, including `new` are overloaded). – littleadv Apr 08 '11 at 03:26