Advertisement

Use of new and delete

Started by June 03, 2001 01:16 AM
5 comments, last by PugPenguin 23 years, 8 months ago
Greetings, I'd like to ask few questions on new and delete. I'm very much used to using malloc() and free(), and I feel uncomfortable with new/delete... so I'm attempting to overcome that. --[1]-- If I do the following: int *i; i = new int; or: int *i; i = new int[10]; am I right that I only need to do: delete i; to deallocate memory? --[2]-- Say, I have a structure: typedef struct _test_tag { struct _test_tag one; struct _test_tag two; // or whatever } TEST; and I allocate memory for 1D array: TEST* hello; hello = new TEST[10]; do I use delete or delete[]? Turbo C/C++ Complete Reference 2nd Edition (1992) by Shildt writes:
quote:
When you free a dynamically allocated array of objects that have destructor functions , you must use this form of delete: delete[] pointer_var;
In this case, TEST is a structure and it doesn't have a destructor. Hence delete hello should be ok. However, in online doc that comes with VC++5, it says:
quote:
If pointer points to an array, place empty brackets before pointer.
According to this, I should do delete[] hello as it's a 1D array. Those two contradicts each other if it's seen as an array. Or is new TEST[10] even seen as an array? or is it equivalent to (TEST*)malloc( sizeof(TEST)*10 )? That wouldn't be an array. I'm wondering how it should be according to the modern C++ spec. --[3]-- Would: int* i; i = new int[10]; the same as the following?: int* i; i = new int[2*5]; and the same as the following?: int* i; i = new int[2][5]; or would that mean five 1D-array of 2-ints? If so (and only if so), would I HAVE to do this?: int* i[5]; i = new int[2][5]; Or can I get away with the former one? I believe all of above allocate 10 ints. But am I right that the last one requires the use of delete[], while the former ones don't??? --[4]-- I understand that type casting is done automatically if you use new. So, if I do the following: int* i = new int[size ]; then size is the multiple value of ints? So, given that int is 2 bytes, that allocates size x 2 bytes? Or is it just 2 bytes, and the preceeding 'int' is a form of type-casting? (If it is type casting, then the statement that type cast is done 'automatically' sounds like a bit of a cheat, if you see what I mean...) That allocating size x 2 bytes is dodgy - so I believe that's wrong. Otherwise the following two: int* i = new int[2]; int* i = new char[4]; would allocate the same amount of memory, which is 4 bytes. That would be bizarre, so that must be wrong... But then, on the other hand, if type casting is done automatically, then the 2nd one should also work... So here, I'm a little confused because they all sound correct depending on perspective (and the others sound wrong at other times). --[5]-- Finally, if I can do: int* i; i = new int (0); to allocate memory for i and initialize it to Zero, then can I also do: int* i[1]; i = new int[1][2] (0); to have i[0]=0 and i[1]=0? It seems to make sense... but also seems bizarre and ambiguous. --[X]-- On a different note (not relating to new and delete), if I do: TEST* hello; hello = new TEST; memset( hello, 0, sizeof(TEST) ); would that memset set all its member pointers to NULL? If NULL=0 by compiler definition, then that seems to make sense (but I don't know that). ------- Thank you, and please reply where you can, even if you can't reply to all! Edited by - PugPenguin on June 3, 2001 2:27:00 AM
1) No. Anytime you allocate an array (new int[10]) you have to free it with delete[]

2) See #1. ALWAYS use delete[] when freeing an array of elements. Only use delete to free a single instance. Your life will be much easier if you follow this ''rule.''

3) The first two examples are equivalent and both need delete[].

As for the third, I could be wrong, but I don''t believe that will even compile. Not sure though. Usually, to allocate a 2d array, you''d do something like
int **i;
i = new int[2];
for(int counter = 0; counter < 2; counter++)
{
i[counter] = new int[5];
}
To delete this, you''d need to first loop and delete each element of i with delete[] and then delete i itself with delete[].

4) Well, if you did in fact have 16 bit ints (old compiler?) then you are allocating the same amount of memory with new int[2] and new char[4]. However, I think that most compilers will give you a type mismatch with the new char[4]. (then again you always can specifically type cast it to an int*) You probably don''t really need to worry about how many bytes you are allocating in most instances. Just know that you have 2 ints. Don''t worry how many bytes it is.

5) Once again, not sure if that compiles, so I don''t know.

X) That would fill your whole TEST structure with zeroes.
NULL == 0 in virtually every circumstance
Advertisement
I made some critical errors in asking the questions, sorry. Let me correct it here:

Where I wrote:

int* i[5];
i = new int[2][5];

It should''ve been:

int (*i)[5];
i = new int[2][5];

(and I just figured [5] at declaration is always necessary)

Similarly:

int (*i)[5][1];
i = new int[2][5][1];

would work... confusing.
Initializer doesn''t work for arrays.. I''ve figured

All in all, I find all this new/delete confusing... alright, delete wasn''t as bad as I thought. But new seems like an overkill for regular memory allocation. It seems I''ll just use them for triggering de/constructors, but else I''m going back to good ole malloc and free... particularly when working with graphics I hate to not know how many bytes I''m using for what etc. And having to use loops for allocating arrays is ludicrous!

Thank you anyway, you''ve cleared up some fog for me
--[1]--

This one is compiler dependent. Alot of compilers will do it right if you just use delete, but using delete[] would be a good idea anyways.

check out http://www.glenmccl.com/bett_003.htm

--[2]--

I think the same applies here.

--[3]--

The first three all allocate essentially the same thing. The last one is syntactically incorrect.

--[4]--

int* i = new int[2]; -- works
int* i = new char[4]; -- doesn''t work.

Like jaxson said, think about how many ints you have, not bytes.

--[5]--
int* i;
i = new int (0);

This works, and its neccesary to do this with objects that don''t have a default constructor.

int* i[1];
i = new int[1][2] (0);

This won''t work. Both the initializer and the new.
This is an array of pointers to integers, so you''d have to do:

int* i[1];
i[0] = new int[2] = {0,0};

--[X]--

TEST* hello;
hello = new TEST;
memset( hello, 0, sizeof(TEST) );

If test is a struct that contains only other structs or basic types this is ok, if there are classes involved anywhere don''t do this. The classes constructors should handle stuff like this.
quote:
Original post by hamhed
This is an array of pointers to integers, so you''d have to do:

int* i[1];
i[0] = new int[2] = {0,0};



Ah, very nice Thank you!
well remember that the major difference between malloc and new
(free and delete)
that when you new a class or a structure(with a constructor)
it will call the constructor automatically for you...

if it would be malloc like how new is works
myclass c = malloc(sizeof(myclass));
c.myclass();

get the idea?

same for delete it calls the destructor unlike free which just frees the memory

so usually don''t mess up with a pointer of new and a pointer of malloc unless you know what you really do

good luck

Arkon
[QSoft Systems]
Advertisement
With regards to [2]
quote:

int* i;
i = new int[2][5];

or would that mean five 1D-array of 2-ints? If so (and only if so), would I HAVE to do this?:

int* i[5];
i = new int[2][5];

Or can I get away with the former one?



quote:

As for the third, I could be wrong, but I don''t believe that will even compile. Not sure though. Usually, to allocate a 2d array, you''d do something like
int **i;
i = new int[2];
for(int counter = 0; counter < 2; counter++)
{
i[counter] = new int[5];
}
To delete this, you''d need to first loop and delete each element of i with delete[] and then delete i itself with delete[].


You''re quite right: it wouldn''t compile, but only because it''s slightly wrong. There''s no need to do it how you said. As the penguin said in his corrected example, you can do it like this:

quote:

int (*i)[5];
i = new int[2][5];




quote:

The last one is syntactically incorrect.


No it''s not. In the corrected example there is nothing wrong with the code.

To allocate a multidimensional array, you just have to bear in mind that when calling new to allocate an array, the return type keeps the size of all but the left-hand most array dimension.


int * i; //pointer to int
i=new int[10] //returns a pointer to an int

int (*i)[5];//pointer to array of 5 ints
i=new int[2][5];//returns a pointer to an array of ints

or

int (*i)[5][2];
i=new int[10][5][2];

etc...

www.elf-stone.com

____________________________________________________________www.elf-stone.com | Automated GL Extension Loading: GLee 5.00 for Win32 and Linux

This topic is closed to new replies.

Advertisement