The new operator

S

sarathy

Hi all,
I was wondering how the program below was working. I
overloaded the new operator, which is responsible for allocating memory
for the object. But I made an explicit memory allocation [ zero bytes
]. When the object was created, somehow the value was assigned
correctly and it prints the correct result. How is this possible ???

# include <iostream>



using namespace std;



class A
{
long a;
public:
A(long x) { a=x; }
long getA(){return this->a;}
void* operator new (size_t);
void operator delete (void *);
};



void* A::eek:perator new (size_t size)
{
void *ptr = malloc(0);
return ptr;
}



void A::eek:perator delete (void *p)
{
free(p);
}

int main()
{
A *a=new A(1234567);
cout << a->getA() << endl;
delete a;
return 0;
}
 
A

Alan Johnson

sarathy said:
Hi all,
I was wondering how the program below was working. I
overloaded the new operator, which is responsible for allocating memory
for the object. But I made an explicit memory allocation [ zero bytes
]. When the object was created, somehow the value was assigned
correctly and it prints the correct result. How is this possible ???

# include <iostream>



using namespace std;



class A
{
long a;
public:
A(long x) { a=x; }
long getA(){return this->a;}
void* operator new (size_t);
void operator delete (void *);
};



void* A::eek:perator new (size_t size)
{
void *ptr = malloc(0);
return ptr;
}



void A::eek:perator delete (void *p)
{
free(p);
}

int main()
{
A *a=new A(1234567);
cout << a->getA() << endl;
delete a;
return 0;
}

What you have is undefined behavior, which means anything could happen,
including appearing to "work" correctly.
 
J

John Carson

sarathy said:
Hi all,
I was wondering how the program below was working. I
overloaded the new operator, which is responsible for allocating
memory for the object. But I made an explicit memory allocation [
zero bytes ]. When the object was created, somehow the value was
assigned correctly and it prints the correct result. How is this
possible ???

I believe that the result of a malloc call with a zero argument is
implementation defined. malloc can either return a NULL pointer or it can
return a unique pointer to a zero amount of memory. The VC++ docs say this
about malloc:

"If size is 0, malloc allocates a zero-length item in the heap and returns a
valid pointer to that item."

See below.

# include <iostream>



using namespace std;



class A
{
long a;
public:
A(long x) { a=x; }
long getA(){return this->a;}
void* operator new (size_t);
void operator delete (void *);
};



void* A::eek:perator new (size_t size)
{
void *ptr = malloc(0);
return ptr;
}



void A::eek:perator delete (void *p)
{
free(p);
}

int main()
{
A *a=new A(1234567);

Pointer a ends up pointing somewhere on the heap and then the constructor
writes an A object to the memory that a points to. Because a zero amount of
memory has been allocated, this involves writing on memory that hasn't been
allocated for the purpose, so your application is likely to crash or
otherwise misbehave. However, it may behave well enough for the constructor
to write the integer to A's member variable and for getA() to retrieve it.
 
R

Ron Natalie

John said:
I believe that the result of a malloc call with a zero argument is
implementation defined. malloc can either return a NULL pointer or it can
return a unique pointer to a zero amount of memory. The VC++ docs say this
about malloc:

"If size is 0, malloc allocates a zero-length item in the heap and returns a
valid pointer to that item."

Which is what the standard says. It's not implementation defined. An
implementation that returns zero to malloc(0) is non-standard.
 
J

John Carson

Ron Natalie said:
Which is what the standard says. It's not implementation defined. An
implementation that returns zero to malloc(0) is non-standard.


I am sceptical of this. I can't find anything in the C++ Standard that says
it (and the C standard definitely makes the behaviour implementation
dependent). Further, typing in malloc(0) in Google Groups for this newsgroup
and its moderated counterpart yields various threads in which knowledgeable
people make the same statement that I did or don't contradict other people
when they make the statement.
 
M

Marcus Kwok

John Carson said:
I am sceptical of this. I can't find anything in the C++ Standard that says
it (and the C standard definitely makes the behaviour implementation
dependent). Further, typing in malloc(0) in Google Groups for this newsgroup
and its moderated counterpart yields various threads in which knowledgeable
people make the same statement that I did or don't contradict other people
when they make the statement.

I agree with John Carson, plus there is the entry in the C FAQ:

http://www.c-faq.com/ansi/malloc0.html

Q: What should malloc(0) do? Return a null pointer or a pointer to 0
bytes?

A: The ANSI/ISO Standard says that it may do either; the behavior is
implementation-defined (see question 11.33). Portable code must
either take care not to call malloc(0), or be prepared for the
possibility of a null return.

[Question 11.33 just defines the differences among
implementation-defined, unspecified, and undefined behavior]
 
D

Default User

Ron said:
Which is what the standard says. It's not implementation defined.
An implementation that returns zero to malloc(0) is non-standard.


I don't think the C++ Standard says that, or much about malloc() at
all. It's a C library function, and behavior is controlled by the C
Standard. The C99 draft Standard says:

7.20.3 Memory management functions

[#1] The order and contiguity of storage allocated by
successive calls to the calloc, malloc, and realloc
functions is unspecified. The pointer returned if the
allocation succeeds is suitably aligned so that it may be
assigned to a pointer to any type of object and then used to
access such an object or an array of such objects in the
space allocated (until the space is explicitly freed or
reallocated). Each such allocation shall yield a pointer to
an object disjoint from any other object. The pointer
returned points to the start (lowest byte address) of the
allocated space. If the space cannot be allocated, a null
pointer is returned. If the size of the space requested is
zero, the behavior is implementation-defined: either a null
pointer is returned, or the behavior is as if the size were
some nonzero value, except that the returned pointer shall
not be used to access an object. The value of a pointer
that refers to freed space is indeterminate.



Naturally, there could be a change in the actual Standard, but I don't
believe so.



Brian
 
J

Jerry Coffin

01.sydney.pipenetworks.com.au>, (e-mail address removed)
says...

[ ... ]
I am sceptical of this. I can't find anything in the C++ Standard that says
it (and the C standard definitely makes the behaviour implementation
dependent). Further, typing in malloc(0) in Google Groups for this newsgroup
and its moderated counterpart yields various threads in which knowledgeable
people make the same statement that I did or don't contradict other people
when they make the statement.

You're right. The current version of C++ (i.e. the 2003 version) lists
C99 as a normative reference.

In C99 ($7.20.3) it says:

If the size of the space requested is zero, the behavior
is implementation-defined: either a null pointer is
returned, or the behavior is as if the size were some
nonzero value, except that the returned pointer shall not
be used to access an object.

The C++ requirements are covered in section 20.4.6:

3 The functions calloc(), malloc(), and realloc() do not
attempt to allocate storage by calling ::eek:perator new()
(18.4).
4 The function free() does not attempt to deallocate
storage by calling ::eek:perator delete().

So, in C++ (just as in C) malloc(0) can return either a null pointer, or
a some unique non-null pointer.

I suppose if somebody wanted to badly enough, they'd have some (minimal)
foundation for claiming ambiguity in C++ on this point though -- C++
2003 contains an inaccurate cross reference to the wrong section of the
C standard (to section 7.11.2 instead of 7.20.3, where the description
of malloc now lives).
 

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

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,165
Latest member
JavierBrak
Top