delete [] operator

N

Nishi

hi..

I was experimenting with new and delete operators. I ended up
getting something I didnt understand. I allocated memory to a char
pointer, and even after freeing the memory, I still got 'hello world'
printed twice. Also if I replace char* with int*, the freeing of
memory will generate the second output 0. Why does this happen?? If
using int*, freeing of memory means the value is reset to 0, why
doesnt the same happen in char * ??

using namespace std;

#include <iostream>
#include <conio.h>

char* allocate(char *, int);

int main()
{
char *str;
str = allocate(str, 100);
str = "hello world";
cout << str;
delete []str;
cout << endl << str;
getch();
return 0;
}

char * allocate(char *s, int size)
{
s = new char[size];
return s;
}
 
K

kasthurirangan.balaji

hi..

     I was experimenting with new and delete operators. I ended up
getting something I didnt understand. I allocated memory to a char
pointer, and even after freeing the memory, I still got 'hello world'
printed twice. Also if I replace char* with int*, the freeing of
memory will generate the second output 0.  Why does this happen?? If
using int*, freeing of memory means the value is reset to 0, why
doesnt the same happen in char * ??

Did you really compile this code???
using namespace std;

#include <iostream>
#include <conio.h>

char* allocate(char *, int);

int main()
{
    char *str;
    str = allocate(str, 100);
    str = "hello world";

compilation should have broken here!!! str is of char type and it
doesn't have any overloaded = operator.Ideally, strcpy should have
been used.
    cout << str;
    delete []str;
    cout << endl << str;
    getch();
    return 0;

}

char * allocate(char *s, int size)
{
     s = new char[size];
     return s;
 }

I guess retaining value of deleted/freed memory is platform dependent.
It didn't occur here. Could also be compiler dependent.

Thanks,
Balaji.
 
T

Torsten Mueller

This program is complicated:
char *str;

You declare a char pointer.
str = allocate(str, 100);

You allocate memory and assign this to the char pointer.
str = "hello world";

You assign a string literal (this is a constant character string) to
the char pointer. Your allocated memory is getting lost here.
cout << str;

You print out the string literal.
delete []str;

You try to delete the string literal. The result of this operation is
undefined, I think.
cout << endl << str;

You print out a pointer to officially deleted memory. This can work in
your case because I guess the delete operation does nothing with the
string literal. So the char pointer does still point to an existing
string. Normally using a deleted pointer will cause a general
protection failure. You have to know if a pointer is deleted or not.

You would like the allocated buffer to get the value "hello world".
This isn't done by assigning a literal but by copying a literal. Use
the function strcpy().

T.M.

P.S.: I always found it much better to write "char* str" instead of
"char *str". The asterisk is part of the type, not part of the symbol.
I do indeed also write "delete[] str" instead of "delete []str".
 
K

Kira Yamato

[...]
P.S.: I always found it much better to write "char* str" instead of
"char *str". The asterisk is part of the type, not part of the symbol.

Actually, it is better to write
char *str;
than to write
char* str;

Reason? The following line
char* s1, s2;
can be misinterpreted to be declaring two pointers to characters, if
you think the asterisk is part of the type when it is really more a
part of the identifier.

On the other hand, writing
char *s1, s2;
makes it a bit more clear that s1 is a pointer to character while s2 is
just a plain character.
 
P

pelio

Torsten Mueller a écrit :
You would like the allocated buffer to get the value "hello world".
This isn't done by assigning a literal but by copying a literal. Use
the function strcpy().

T.M.

P.S.: I always found it much better to write "char* str" instead of
"char *str". The asterisk is part of the type, not part of the symbol.
I do indeed also write "delete[] str" instead of "delete []str".

I would rather:

int *pi, i; // * before the name makes clear it is a pointer

as opposed to:

int* pi, i; // i is int not int*


delete[] is an operator by itself (same as operator delete) so it makes
sense to write delete[]

Just the way i see it. :)
 
I

Ian Collins

Nishi said:
hi..

I was experimenting with new and delete operators. I ended up
getting something I didnt understand. I allocated memory to a char
pointer, and even after freeing the memory, I still got 'hello world'
printed twice.

You didn't free the memory, you attempted to free a string literal.
This may make your toilet explode.
Also if I replace char* with int*, the freeing of
memory will generate the second output 0. Why does this happen??

Anything can happen, dereferencing a freed pointer invokes the demons of
undefined behaviour. This may make your toilet explode.
If using int*, freeing of memory means the value is reset to 0, why
doesnt the same happen in char * ??
It dose not.
using namespace std;
Don't do this before your includes.
#include <iostream>
#include <conio.h> ?

char* allocate(char *, int);

int main()
{
char *str;
str = allocate(str, 100);
str = "hello world";

Leaks the memory allocated for str.
 
I

Ian Collins

Kira said:
[...]
P.S.: I always found it much better to write "char* str" instead of
"char *str". The asterisk is part of the type, not part of the symbol.

Actually, it is better to write
char *str;
than to write
char* str;

Reason? The following line
char* s1, s2;
can be misinterpreted to be declaring two pointers to characters, if you
think the asterisk is part of the type when it is really more a part of
the identifier.

On the other hand, writing
char *s1, s2;
makes it a bit more clear that s1 is a pointer to character while s2 is
just a plain character.
A better rule is to only declare one variable per line.
 
T

Torsten Mueller

Kira Yamato said:
Actually, it is better to write
char *str;
than to write
char* str;

Reason? The following line
char* s1, s2;
can be misinterpreted

I just *do never* define more than one symbol on a line.

It is much more important for me to use a notation which separates the
type from the symbol. The type is "pointer to char" and the symbol is
"str". If the asterisk is located near the symbol this principle is
completely disturbed. This confuses especially beginners. It could
then be read as something like "char is the type of the dereferenced
pointer str" which seems to me like "thinking around corners". It
hides also the aspect of being a buffer with a length. "char" is one
character for me.

T.M.
 
P

Pete Becker

compilation should have broken here!!! str is of char type and it
doesn't have any overloaded = operator.Ideally, strcpy should have
been used.

str is of type char*, not char. Pointers can be assigned. Yes, strcpy
should have been used. As written, the second assignment throws away
the address stored by the first one.
 
C

Chandra Shekhar

using namespace std;

#include <iostream>
#include <conio.h>

char* allocate(char *, int);

int main()
{
char *str;
str = allocate(str, 100);

I think this is not the way of assigning a string to a
char*. 'strcpy' should had been used instead.
str = "hello world";
cout << str;

also str is a char* and not char*[]. applying delete[] on char*
instead of char*[] is also possibly a culprit in the behavior of the
program. Try changing it to 'delete str' and then try....
delete []str;
cout << endl << str;
getch();
return 0;

}

char * allocate(char *s, int size)
{
s = new char[size];
return s;
}

The rest of the code is fine.

Chandra Shekhar
([email protected], (e-mail address removed), (e-mail address removed))
 
P

Pete Becker

using namespace std;

#include <iostream>
#include <conio.h>

char* allocate(char *, int);

int main()
{
char *str;
str = allocate(str, 100);

I think this is not the way of assigning a string to a
char*. 'strcpy' should had been used instead.
str = "hello world";
cout << str;

also str is a char* and not char*[]. applying delete[] on char*
instead of char*[] is also possibly a culprit in the behavior of the
program. Try changing it to 'delete str' and then try....

str is, indeed, a char*. The call to allocate() allocates an array of
char, so the proper way to dispose of the memory is delete[] str.
char * allocate(char *s, int size)
{
s = new char[size];
return s;
}
 
R

Rolf Magnus

pelio said:
Torsten Mueller a écrit :
You would like the allocated buffer to get the value "hello world".
This isn't done by assigning a literal but by copying a literal. Use
the function strcpy().

T.M.

P.S.: I always found it much better to write "char* str" instead of
"char *str". The asterisk is part of the type, not part of the symbol.
I do indeed also write "delete[] str" instead of "delete []str".

I would rather:

int *pi, i; // * before the name makes clear it is a pointer

as opposed to:

int* pi, i; // i is int not int*

I think both are about equally ugly, and I would prefer:

int* pi;
int i;
 
K

Kira Yamato

I just *do never* define more than one symbol on a line.

I mostly agree with you on that point. But saying "never" seems a bit
too presumptuous.
It is much more important for me to use a notation which separates the
type from the symbol. The type is "pointer to char" and the symbol is
"str". If the asterisk is located near the symbol this principle is
completely disturbed.

But this does not negate the fact that the C++ grammar does in fact
bind the asterisk tighter to the identifier than to the type being
pointed to.

I'm just saying that it is better to write code that reflects the
intention of the grammar.
This confuses especially beginners. It could
then be read as something like "char is the type of the dereferenced
pointer str" which seems to me like "thinking around corners". It
hides also the aspect of being a buffer with a length. "char" is one
character for me.

Granted. If the beginner never declares more than 1 variable per line,
then it does not matter. However, someday the beginner will likely try
to declare more than 1 variable per line. (I know I had.) So, when
that day comes, doing it your way will confuse the beginner as to why
only his variable is a pointer while the rest of his variables are not.

So, I would say that your way would confuse the beginners more.
 
J

James Kanze

On 2008-01-29 03:14:37 -0500, Torsten Mueller
<[email protected]> said:
I mostly agree with you on that point. But saying "never"
seems a bit too presumptuous.

Not in this case. The C++ grammar contains enough traps for the
beginner, without making it harder than it has to be.
But this does not negate the fact that the C++ grammar does in
fact bind the asterisk tighter to the identifier than to the
type being pointed to.
I'm just saying that it is better to write code that reflects the
intention of the grammar.

The intention of the grammar, here, is to be compatible with C.
At a higher level, the intention of the language is to make the
type system mean something. Conceptually, it's "char*" you're
interested in, not "char".
Granted. If the beginner never declares more than 1 variable
per line, then it does not matter. However, someday the
beginner will likely try to declare more than 1 variable per
line. (I know I had.) So, when that day comes, doing it your
way will confuse the beginner as to why only his variable is a
pointer while the rest of his variables are not.
So, I would say that your way would confuse the beginners more.

Not if the beginner is told not to declare more than one
variable per line.
 
T

Torsten Mueller

Kira Yamato said:
But this does not negate the fact that the C++ grammar does in fact
bind the asterisk tighter to the identifier than to the type being
pointed to.

It does not make *any* sense to write "int *pi" except the *one*
situation you have more than a single definition on the same line.

The fact that the grammar does bind the asterisk more to the right
side than to the left is one of the things that give the C language
the myth to be complicated. I could also say this is one of the lacks
in language design. Why does "int* a,b,c;" indeed not define just
three pointers? What's the reason for this? Is there any???

I try to avoid these situations for about 20 years now. I never define
pointers and non-pointers on the same line and I also tell beginners
not to do this, also for other reasons (a lot of tools and browsers
can read but not write such definitions).
I'm just saying that it is better to write code that reflects the
intention of the grammar.

I want my code reflecting *my* intention :) In my experience this
leads mostly to code which is good readable by other humans and also
compilable by machines.

T.M.
 
N

Nishi

thanks for the replies..
I made a stupid mistake, should have used strcpy instead of direct
assignment.
Just a single change, and the code works perfectly fine.
thanks again.
 

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
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top