How would you compare C’s malloc and free functions with C++’s new and delete operators in terms of safety?
How would you compare C’s malloc and free functions with C++’s new and delete operators in terms of safety?
What do you mean "safety" ?
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
I guess in the sense that this is legal in C:
main() {
int a[5];
*( a + 7 ) = 1;
a[ 9 ] = 5;
}
To be honest, its a homework question for Programming Languages, a senior level computer science course. I'm not exactly sure of the professor's meaning here.
>How would you compare C’s malloc and free functions with C++’s new and delete operators in terms of safety?
Well, free is easier to get right than delete, so it's probably "safer" in terms of shooting yourself in the foot. The simplified syntax of new is slightly more dummy resistant than malloc, so it's probably "safer" for the average programmer.
>I guess in the sense that this is legal in C
Except for the lack of a return type for main, it's legal in C++ too. Of course, that example has precisely nothing to do with new and delete or malloc and free.
My best code is written with the delete key.
Well
a = new int[10];
a = malloc ( 10 * sizeof *a );
Both allocate space for 10 int's.
Neither prevents you from doing dumb stuff like
a[20] = 0;
New is a bit safer in that it's harder to screw up on getting the type wrong.
But your example has nothing to do with malloc / new, only that it shows the flexibility with which you can use either pointer notation or array notation to access either arrays or allocated memory.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
How is new more dummy resistant than malloc? I realize my example has nothing to do with malloc/new, I just meant "safety" in terms of shooting yourself in the foot. And my example shows that you can reference memory locations outside of an array.
Last edited by groberts1980; 10-17-2006 at 02:44 PM.
>How is new more dummy resistant than malloc?
Let's say you want 10 integers. To do so with malloc involves a size calculation:
It's easy to get wrong if you aren't careful, especially since so many people keep wanting to use explicit types:Code:int *p = malloc ( 10 * sizeof *p );
Now, the same thing in C++ is almost as simple as an array declaration:Code:int *p = malloc ( 10 * sizeof ( int ) );
Simpler, more consistent syntax promotes dummy resistance.Code:int *p = new int[10];
My best code is written with the delete key.
Okay Prelude, I'll bite. I just re-read your FAQ so that I'd know your stance _FIRST_.
Now I ask you: What would be the problem with using sizeof(int) there? There is no way for sizeof(int) to return anything but 4 for a 32 bit OS. If one moves to a 64 bit OS, then one has to completely recompile anyways, which would then make it return 8. Likewise, for a 16 bit OS, the return value would be 2. So, why would that be "wrong"?Originally Posted by Prelude
I question the reasoning of your FAQ on the basis that growing/shrinking any structure would create a rebuild if any of the headers are changed, given that one is smart enough to properly format a makefile, or whatever type build it is.
If I'm not mistaken, new also calls the constructors (and delete calls destructors), which malloc doesn't. So, if it is C++, you can't use one in place of another. And if it is C, you won't have new?
No it isn't legal. You cannot access past the end of an array, other than to compare the address of "one past the end of the array". Even then you're only allowed to check the address of the location, you are not allowed to modify it. You cannot access past the end of an array.Originally Posted by groberts1980
It will compile, because C doesn't do boundry checking. However, it's still not allowed.
Quzah.
Hope is the first step on the road to disappointment.
Kennedy, in the very same FAQ it reads:
And apparently Prelude doesn't care what you do as long as you are consistent in your usage.Originally Posted by Prelude
There's nothing really wrong with using the size of the data type. It's just easier to avoid messing up by using "sizeof *p" in the event you change the type down the road. Using the a data type in there means you have to go find all of your allocations later when you change what type p is. If you happen to miss one, you'll potentially introduce some bugs into your program, which can be a real pain in the ass to track down.
Quzah.
Hope is the first step on the road to disappointment.
So, the point of the using *var in place of sizeof(type) is just that if you change your type later then you don't have to correct the rest of your code?
Well, okay, sure. . . I guess I could see that. However, one would still have to run through with a fine-toothed comb to ensure that there were no assignments that were invalid. . .
The bottom line, then, is that one shouldn't say that this behaviour is "wrong".
Edit: Bummer, beaten to it.
Originally Posted by quzah
So, it will compile. And it will run. With unintended consequences, but it'll run. How is that "not allowed"? C does not do boundry checking. Technically, you CAN do that. You can read and write a[ 10 ] when "a" only has 5 elements. C will let you do it.
It's "not allowed" by the standard. The syntax is fine. It's not a syntax error. Thus, it compiles. Thus it runs. However, it is not allowed by the standard. You are not allowed to run off the ends of your array and have that be defined behavior.
Quzah.
Hope is the first step on the road to disappointment.