473,854 Members | 1,513 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

May the size argument of operator new overflow?

Hello!

Does the C++ standard define what happens when the size argument of void*
operator new(size_t size) cannot represent the total number of bytes to be
allocated? For example:

struct S
{
char a[64];
};

S* allocate(int size)
{
return new S[size]; // What happens here?
}

int main()
{
allocate(0x7FFF FFFF);
}
Jun 27 '08 #1
30 2699
Angel Tsankov wrote:
Hello!

Does the C++ standard define what happens when the size argument of void*
operator new(size_t size) cannot represent the total number of bytes to be
allocated? For example:
size_t will always be wide enough to represent the maximum memory range
on a given system.

If the system can't supply the requested size, new throws std::bad_alloc.

--
Ian Collins.
Jun 27 '08 #2
On Jun 18, 5:44*am, "Angel Tsankov" <fn42...@fmi.un i-sofia.bgwrote:
Hello!

Does the C++ standard define what happens when the size argument of void*
operator new(size_t size) cannot represent the total number of bytes to be
allocated? For example:
Yes. You cannot exceed numeric_limits< size_t>::max(). The same is
true for array size.
Jun 27 '08 #3
Hello!
>
Does the C++ standard define what happens when the size argument of void*
operator new(size_t size) cannot represent the total number of bytes to be
allocated? For example:
Yes. You cannot exceed numeric_limits< size_t>::max(). The same is
true for array size.

OK, but what happens in the example that you have cut off?
Jun 27 '08 #4
>Hello!
>>
Does the C++ standard define what happens when the size argument of void*
operator new(size_t size) cannot represent the total number of bytes to
be
allocated? For example:
size_t will always be wide enough to represent the maximum memory range
on a given system.

If the system can't supply the requested size, new throws std::bad_alloc.
This is not an answer to the question what happens in the example you have
cut off.
Jun 27 '08 #5
Angel Tsankov wrote:

[please don't snip attributions]
Bo Persson wrote:
>Here is what one compiler does - catch the overflow and wrap it back to
numeric_limits <size_t>::max() .

int main()
{
allocate(0x7FF FFFFF);
00401000 xor ecx,ecx
00401002 mov eax,7FFFFFFFh
00401007 mov edx,40h
0040100C mul eax,edx
0040100E seto cl
00401011 neg ecx
00401013 or ecx,eax
00401015 push ecx
00401016 call operator new[] (401021h)
0040101B add esp,4
}
0040101E xor eax,eax
00401020 ret

Yes, the size requested is rounded to the maximum allocatable size, but is
this standard-compliant behavior? And if it is, how is client code notified
of the rounding?
Your question has nothing to do with operator new() and everything to do
with integer overflow.

The reason some of us answered the way we did is probably because we are
used to systems where sizeof(int) == 4 and sizeof(size_t) == 8, so your
original code would simply have requested 32GB, not a lot on some systems.

--
Ian Collins.
Jun 27 '08 #6
Jerry Coffin <jc*****@taeus. comkirjutas:
In article <g3*********@ai oe.org>, fn*****@fmi.uni-sofia.bg says...
>Hello!

Does the C++ standard define what happens when the size argument of
void* operator new(size_t size) cannot represent the total number of
bytes to be allocated? For example:

struct S
{
char a[64];
};

S* allocate(int size)
{
return new S[size]; // What happens here?
}

int main()
{
allocate(0x7FFF FFFF);
}

Chances are pretty good that at some point, you get something like:

void *block = ::new(0x7FFFFFF F*64);

On an implementation with a 32-bit size_t, that'll wraparound, and
it'll attempt to allocate 0xffffffc0 bytes instead of 0x1fffffffc0
bytes. Chances are that allocation will immediately fail since that
number is _barely_ short of 4 gigabytes, and no 32-bit system I know
of wiil have that much contiguous address space available.

If, OTOH, you picked numbers where the wraparound produced a
relatively small number, chances are that the allocation would
succeed, but when you attempted to access what appeared to be
successfully allocated memory, you'd quickly go past the end of the
real allocation, and get undefined behavior.
The standard says that for too large allocations std::bad_alloc must be
thrown. In the user code there is no unsigned arithmetic done, thus no
wraparound can occur. I would say that if the implementation does not
check for the overflow and silently wraps the result, the implementation
does not conform to the standard. It is irrelevant if the implementation
uses unsigned arithmetics inside, or e.g. double.

I have not studied the standard in detail, so this is just my opinion how
it should work.

Best,
Paavo

Jun 27 '08 #7
Angel Tsankov wrote:
>>>>Does the C++ standard define what happens when the size
argument of void* operator new(size_t size) cannot represent
the total number of bytes to be allocated?

For example:

struct S
{
char a[64];
};

S* allocate(int size)
{
return new S[size]; // What happens here?
}

int main()
{
allocate(0x7FFF FFFF);
}

Supposing that all values in an int can be represented in a
size_t (i.e. that size_t is unsigned int or larger---very, very
probably), then you should either get the memory, or get a
bad_alloc exception (which you don't catch). That's according
to the standard; a lot of implementations seem to have bugs
here.

I think, you are missing a twist that the OP has hidden within his
posting: the size of S is at least 64. The number of S objects
that he requests is close to numeric_limits< size_t>::max(). So
when new S[size] is translated into raw memory allocation, the
number of bytes (not the number of S objects) requested might
exceed numeric_limits< size_t>::max().

Thanks for pointing this out, I though it would be obvious to
everyone. The following example might be a little bit less
confusing:
struct S
{
char a[64]; // Any size greater than 1 would do.
};

S* allocate(std::s ize_t size)
{
return new S[size]; // How many bytes of memory must the new
operator allocate if size equals std::numeric_li mits<size_t>::m ax()?
}
>>I think (based on my understanding of [5.3.4/12]) that in such a
case, the unsigned arithmetic will just silently overflow and you
end up allocating a probably unexpected amount of memory.

Here is what one compiler does - catch the overflow and wrap it
back to numeric_limits< size_t>::max().

int main()
{
allocate(0x7FF FFFFF);
00401000 xor ecx,ecx
00401002 mov eax,7FFFFFFFh
00401007 mov edx,40h
0040100C mul eax,edx
0040100E seto cl
00401011 neg ecx
00401013 or ecx,eax
00401015 push ecx
00401016 call operator new[] (401021h)
0040101B add esp,4
}
0040101E xor eax,eax
00401020 ret

Yes, the size requested is rounded to the maximum allocatable size,
but is this standard-compliant behavior? And if it is, how is
client code notified of the rounding?
Requesting a numeric_limits< size_t>::max() allocation size is pretty
much assured to fail with a std::bad_alloc exception.
Bo Persson
Jun 27 '08 #8
On Jun 18, 5:40 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
James Kanze wrote:
On Jun 18, 11:44 am, "Angel Tsankov" <fn42...@fmi.un i-sofia.bgwrote:
Does the C++ standard define what happens when the size
argument of void* operator new(size_t size) cannot represent
the total number of bytes to be allocated?
For example:
struct S
{
char a[64];
};
S* allocate(int size)
{
return new S[size]; // What happens here?
}
int main()
{
allocate(0x7FFF FFFF);
}
Supposing that all values in an int can be represented in a
size_t (i.e. that size_t is unsigned int or larger---very, very
probably), then you should either get the memory, or get a
bad_alloc exception (which you don't catch). That's according
to the standard; a lot of implementations seem to have bugs
here.
I think, you are missing a twist that the OP has hidden within
his posting: the size of S is at least 64. The number of S
objects that he requests is close to
numeric_limits< size_t>::max().
It's not on the systems I usually use, but that's not the point.
So when new S[size] is translated into raw memory allocation,
the number of bytes (not the number of S objects) requested
might exceed numeric_limits< size_t>::max().
And? That's the implementation' s problem, not mine. I don't
see anything in the standard which authorizes special behavior
in this case.
I think (based on my understanding of [5.3.4/12]) that in such
a case, the unsigned arithmetic will just silently overflow
and you end up allocating a probably unexpected amount of
memory.
Could you please point to something in §5.3.4/12 (or elsewhere)
that says anything about "unsigned arithmetic". I only have a
recent draft here, but it doesn't say anything about using
unsigned arithmetic, or that the rules of unsigned arithmetic
apply for this calcule, or even that there is a calcule. (It is
a bit vague, I'll admit, since it says "A new-expression passes
the amount of space requested to the allocation function as the
first argument of type std:: size_t." It doesn't really say
what happens if the "amount of space" isn't representable in a
size_t. But since it's clear that the request can't be honored,
the only reasonable interpretation is that you get a bad_alloc.)

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #9
On Jun 18, 9:16 pm, Ian Collins <ian-n...@hotmail.co mwrote:
Angel Tsankov wrote:
Bo Persson wrote:
Here is what one compiler does - catch the overflow and
wrap it back to numeric_limits< size_t>::max().
int main()
{
allocate(0x7FFF FFFF);
00401000 xor ecx,ecx
00401002 mov eax,7FFFFFFFh
00401007 mov edx,40h
0040100C mul eax,edx
0040100E seto cl
00401011 neg ecx
00401013 or ecx,eax
00401015 push ecx
00401016 call operator new[] (401021h)
0040101B add esp,4
}
0040101E xor eax,eax
00401020 ret
Yes, the size requested is rounded to the maximum
allocatable size, but is this standard-compliant behavior?
If the implementation can be sure that the call to operator
new[] will fail, it's probably the best solution. (This would
be the case, for example, if it really was impossible to
allocate that much memory.)
And if it is, how is client code notified of the rounding?
It doesn't have to be.
Your question has nothing to do with operator new() and
everything to do with integer overflow.
His question concerned operator new. Not unsigned integral
arithmetic.
The reason some of us answered the way we did is probably
because we are used to systems where sizeof(int) == 4 and
sizeof(size_t) == 8, so your original code would simply have
requested 32GB, not a lot on some systems.
Or because we take the standard literally.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

27
14929
by: Marcus Kwok | last post by:
I am getting warnings when comparing a (regular) int to the value returned from std::vector.size() in code similar to the following: int i = //stuff if (i >= vec.size()) The compiler gives me a "signed/unsigned mismatch" warning (I am using the C++ compiler found in Visual Studio .NET 2003, which tells me that the return type is a size_t). I get similar warnings when assigning the
7
4970
by: Jim Cook | last post by:
We have a macro which takes various index constants as an argument and offsets into an array. The macro can be an Lvalue or Rvalue. The index is not zero based. I would like a compile time error displayed if the index is out of bounds. Is there a way to do this well? I read through the FAQ that I could find mentioned, and did not see this sort of question in the preprocessor section anywhere. What I came up with is below. It does in...
55
3171
by: Robotnik | last post by:
Hello All, I want to know if we could know the size of a structyure without the use of sizeof(). Any hints.
9
8825
by: Notebooker | last post by:
Hello, I'm an intermediate noob reading-in data from ascii-file using an ifstream object. I have specified a c-style string buffer with size of type size_t and I am specifying to use this buffer size as the number of characters to read in using the function read(). The issue I am having is read() expects that the value for the number of characters to read-in will be of type std::streamsize, which is apparently signed int. My buffer
5
4202
by: Stepheno | last post by:
Hi, I am a recently converted Iseries (AS/400) RPG programmer trying to learn HTML/CSS/JavsScript all at the same time (not fun). My problem deals mostly with CSS. I will be reveiving a table, for which number of rows/columns i will not know, and I have to pretty up the table, including a verical scroll bar. This has to work in IE6, IE7, and FireFox 3.5. The CSS I currently have will give me a scrollable table, but only if I hard code...
0
9901
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
11025
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10371
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9513
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7915
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
7082
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5743
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4562
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4159
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.