What would new (char([0])) give?

P

Pep

I have been investigating a piece of code that deals with buffers and have
the real possibility that after a convoluted algorithm to determine the
length of the desired buffer is executed, the applcation could attempt to
allocate a buffer of zero size!

Could you tell me the effects of the following piece of code?

#include <iostream>
#include <stdio.h>

using namespace std;

int main(int argc, char** argv)
{
char* ptr0 = new (char([0]));
char* ptr100 = new (char([100]));

cout << "ptr100 [" << ptr100 << "] ptr0 [" << ptr0 << "]" << endl;

sprintf(ptr100, "this is ptr100");
cout << "ptr100 " << ptr100 << endl;

sprintf(ptr0, "this is ptr0");
cout << "ptr0 " << ptr0 << endl;

printf("ptr100 [%p] ptr0 [%p]\n", ptr100, ptr0);

return(0);
}

This is the output of the applicattion

ptr100 [] ptr0 []
ptr100 this is ptr100
ptr0 this is ptr0
ptr100 [0x804a018] ptr0 [0x804a008]
 
M

mlimber

Pep said:
I have been investigating a piece of code that deals with buffers and have
the real possibility that after a convoluted algorithm to determine the
length of the desired buffer is executed, the applcation could attempt to
allocate a buffer of zero size!

This thread deals with the topic in more detail:

http://groups.google.com/group/comp..._frm/thread/d20a4d89f2aa5996#f5ed9ac5334ae733

In short, assuming new does not throw an exception (which it could even
with zero size), a zero-sized array is valid and must be deleted(!) but
dereferencing the returned pointer is undefined.
Could you tell me the effects of the following piece of code?

#include <iostream>
#include <stdio.h>

using namespace std;

int main(int argc, char** argv)
{
char* ptr0 = new (char([0]));
char* ptr100 = new (char([100]));

What's with all those parentheses? You could reduce clutter and improve
readability like this:

char* ptr0 = new char[0];
char* ptr100 = new char[100];
cout << "ptr100 [" << ptr100 << "] ptr0 [" << ptr0 << "]" << endl;

sprintf(ptr100, "this is ptr100");
cout << "ptr100 " << ptr100 << endl;

sprintf(ptr0, "this is ptr0");

^^^^^^
The program is valid except for this line, which implicitly
dereferences ptr0. If it didn't crash, you were lucky. You have
certainly overflowed the buffer, corrupting who knows what, and since
ptr0 is zero-sized, the behavior is undefined.
cout << "ptr0 " << ptr0 << endl;

printf("ptr100 [%p] ptr0 [%p]\n", ptr100, ptr0);

return(0);
}

This is the output of the applicattion

ptr100 [] ptr0 []
ptr100 this is ptr100
ptr0 this is ptr0
ptr100 [0x804a018] ptr0 [0x804a008]

Also, I'd note that you didn't delete the pointers, but since the
program is exiting, that may be irrelevant in practice.

Cheers! --M
 
P

Pep

mlimber said:
This thread deals with the topic in more detail:

http://groups.google.com/group/comp..._frm/thread/d20a4d89f2aa5996#f5ed9ac5334ae733

In short, assuming new does not throw an exception (which it could even
with zero size), a zero-sized array is valid and must be deleted(!) but
dereferencing the returned pointer is undefined.

So having read the included url and your summary, I understand that I can
end up with a valid non-null pointer for a zero sized array that is
actually invalid if dereferenced!
Could you tell me the effects of the following piece of code?

#include <iostream>
#include <stdio.h>

using namespace std;

int main(int argc, char** argv)
{
char* ptr0 = new (char([0]));
char* ptr100 = new (char([100]));

What's with all those parentheses? You could reduce clutter and improve
readability like this:

I have lifted this line of code verbatim from an old working application.
char* ptr0 = new char[0];
char* ptr100 = new char[100];
cout << "ptr100 [" << ptr100 << "] ptr0 [" << ptr0 << "]" <<
endl;

sprintf(ptr100, "this is ptr100");
cout << "ptr100 " << ptr100 << endl;

sprintf(ptr0, "this is ptr0");

^^^^^^
The program is valid except for this line, which implicitly
dereferences ptr0. If it didn't crash, you were lucky. You have
certainly overflowed the buffer, corrupting who knows what, and since
ptr0 is zero-sized, the behavior is undefined.

I thought that was the case but having received a valid pointer back from
the new operator thought I would explore the affects a little bit more.

In point of note the application did not crash in either FreeBSD using G++
2.95.4 or linux using g++ 3.3.5
cout << "ptr0 " << ptr0 << endl;

printf("ptr100 [%p] ptr0 [%p]\n", ptr100, ptr0);

return(0);
}

This is the output of the applicattion

ptr100 [] ptr0 []
ptr100 this is ptr100
ptr0 this is ptr0
ptr100 [0x804a018] ptr0 [0x804a008]

Also, I'd note that you didn't delete the pointers, but since the
program is exiting, that may be irrelevant in practice.

Cheers! --M

True I did not delete the pointers which is sloppy and I will not use the
fact that it is a test application as a excuse :)

BTW, this is a real world problem as opposed to a student question so I
appreciate your input. I will now change the existing program to guard
against 0 size array allocations.

Also the actual program in question uses the incorrect delete operator
instead of the delete[] operator to dispose of the arrays which I am
amending :(

Cheers,
Pep.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top