Re: dynamic array allocation
Well, a is a pointer to the first element in the list, right? So a-1 is one before the beginning of the list, and garbage is stored there. I think you mean *(a+x), which would give the last element in the list. You can't figure it out with a alone.
EDIT: Did not know about the size stored before the block. Maybe some invisible overhead?
Re: dynamic array allocation
You could use a std::vector<chartype> as your string. No problem with embedded nulls but doesn't have strings rich interface. Never rely on new and delete to be implemented in any particular way. Because vectors use contiguous memory the vector<chartype> is compatible with C strings and if you are careful in some instances can be treated as one. Reading is always fine as long as its not being modified elsewhere. modifying can be dangerous without care.
Why would you want to work with numeric arrays without knowing the size? Due to arrays decaying to pointers on passing as a parameter, the size becomes important information to be passed too. Nowadays you should prefer to avoid bare arrays anyway preferring std::vector or std::array or boost::array.
Re: dynamic array allocation
Quote:
Originally Posted by
ustulation
vector 'delete' knows the amount of memory to free by the count that 'new' inserts just ahead of the allocated block while returning the reference to the beginning of the next word boundary
Please tell us where you got this information, since it isn't correct. That isn't the case for all compilers.
http://www.parashift.com/c++-faq/fre...html#faq-16.14
Quote:
so for "int* a=new int[x];" i'm trying to use "*(a-1)" ... but it's neither returning the (number of elements) nor (number of elements)*sizeof(element) though each time something close to the second value...for instance if x=10 then the returned value is in the range [45 to 49] ...
When you allocate memory, you don't know where or how that number is stored. You're not supposed to know, as that is implementation defined.
Regards,
Paul McKenzie
Re: dynamic array allocation
Quote:
Originally Posted by
Paul McKenzie
Please tell us where you got this information, since it isn't correct. That isn't the case for all compilers.
Bjarne's book..the c++ programming language spc edition Pg., 128....it's very subtle the way its mentioned there (as everything in that book is :) )...then to fully understand i'd to google further...see:
http://blogs.msdn.com/b/oldnewthing/.../03/66660.aspx
Quote:
You're not supposed to know, as that is implementation defined.
if it's known at runtime then we should too :) ...it lets us take so many advantages...how do u use an integer array in a function without passing the size :
void f(int* arr) {/* how do u use arr now? */}
Re: dynamic array allocation
Though personally I still fail to see why its important that you dont pass the size, the simple answer is to use a vector. A vector knows its size and this can be queried with the size() member function. The vector has the advantage too of managing its own memory taking a job off your hands which you would otherwise have had to do yourself when you used new[].
Re: dynamic array allocation
Quote:
Originally Posted by
Russco
Though personally I still fail to see why its important that you dont pass the size, the simple answer is to use a vector. A vector knows its size and this can be queried with the size() member function. The vector has the advantage too of managing its own memory taking a job off your hands which you would otherwise have had to do yourself when you used new[].
i understand and agree to your point completely...i just want to know what's happening ... i'v gone into this b-coz one of my Qt programs kept crashing and was a pain to debug it since i'm not a prolific coder (not my profession) ... found out later that i's using delete[] on a scalar pointer along with several vector pointers (not the std::vector :) ofcourse)...it struck me then...and bjarne wrote this in one such concise statement in a way as if it was intended that everybody missed it :) ... then i googled for it out of curiosity...
btw i'v some finding on this... i see that every time the size comes out to be 9 more bytes than the actual size number of bytes allocated...and those places are initialized to zero...if i free memory within (the size of my array)+(9bytes more) range, things are fine...moment i go further the program crashes randomly...can u use try it in your systems and see if it's consistent this way for array sizes over 9?
Re: dynamic array allocation
You just do not do what you are trying to do with pointers and new ever. Looking after the bookkeeping is up to the compiler and relying on specific implemetation defined behaviour will eventually bite your arm off. What bjarne is telling you is how new CAN be implemented. Its for waffle and interest only. Its not behaviour mandated by the standard and it can not be relied upon. You do not own the memory allocated before your block. Dont go poking around in it.
Re: dynamic array allocation
ok..will avoid it..cheers !!
Re: dynamic array allocation
Quote:
Originally Posted by
ustulation
if it's known at runtime then we should too :) ...it lets us take so many advantages...how do u use an integer array in a function without passing the size :
void f(int* arr) {/* how do u use arr now? */}
You pass the size. Or you encapsulate the array in an object that holds the size for you, like std::vector or std::tr1::array.
If you want to play with things like this, none of us can stop you, but all you're going to learn is how to write code that only works for one compiler.
Re: dynamic array allocation
Quote:
Originally Posted by
ustulation
btw i'v some finding on this... i see that every time the size comes out to be 9 more bytes than the actual size number of bytes allocated...and those places are initialized to zero...if i free memory within (the size of my array)+(9bytes more) range, things are fine...moment i go further the program crashes randomly...can u use try it in your systems and see if it's consistent this way for array sizes over 9?
How do some runtime and third-party allocators know when you overwrite memory? The runtime overallocates, making the extra bytes guard-bytes. If those guard bytes are changed when you deallocate the memory, then the runtime knows you have done something wrong.
So I'll ask you a trick question: How many bytes are allocated with the following statememt:
Code:
char *p = new char[10];
If you say 10 bytes, you are wrong. The correct answer is at least 10 bytes. Nothing stops a debugging version of the runtime to allocate more memory for the purposes I mentioned above.
So what you are trying to do is equivalent of a dog chasing its own tail. You'll keep running around, chasing magic numbers and trying to write code, and then you get tripped up again somewhere.
The bottom line is that a runtime library need not allocate exactly x bytes if you ask for x bytes. It can allocate x bytes, plus any number of other bytes for houskeeping, debugging, or for any other purpose the runtime deems fit.
Also, you say you called delete[] on a scalar, and that is what made you search for these answers -- welcome to the world of C++ programming. All of us here have made errors when handling dynamically allocated memory. That is the contract you make with this language when you write programs that use new/delete. You are responsible for making sure all memory handling is done correctly.
Regards,
Paul McKenzie
Re: dynamic array allocation
Quote:
Originally Posted by
ustulation
if it's known at runtime then we should too :) ...it lets us take so many advantages...how do u use an integer array in a function without passing the size :
void f(int* arr) {/* how do u use arr now? */}
You pass the size. That is how the language has been since the beginning, and since K&R C programming. That's why std::vector and std::array exists in C++, so that you get the size as part of the entire package. A pointer is just a dumb variable -- it knows nothing except that it points to something. It has no special powers beyond that.
Secondly, if your discovery was sound, why do products such as BoundsChecker, Purify, and valgrind still exist?
Regards,
Paul McKenzie
Re: dynamic array allocation
Quote:
Originally Posted by
ustulation
ok..will avoid it..cheers !!
Avoiding isn't good enougth.
You must promise to never ever again even consider making use of C++ language implementation detail ... or else ... or else. Or else you'll be sentenced to using Java for the rest of your natural life.
Re: dynamic array allocation
Quote:
Originally Posted by
nuzzle
Avoiding isn't good enougth.
You must promise to never ever again even consider making use of C++ language implementation detail ... or else ... or else. Or else you'll be sentenced to using Java for the rest of your natural life.
HAHAHAHAHA....thank u all...it's from valuable comments of practical programmers like you that others learn !!
Re: dynamic array allocation
Quote:
Originally Posted by
ustulation
I think that it is great that you searched for more information and then got that article, but next time remember to read what you find closely, e.g., you should have seen:
Quote:
Here's how the Microsoft C++ compiler manages vector allocation. Note that this is internal implementation detail, so it's subject to change at any time, but knowing this may give a better insight into why mixing scalar and vector new/delete is a bad thing.
Re: dynamic array allocation
i read that too..and i got uniform results under Win7, Ubuntu Intrepid and Lucid...but all under GCC/G++ and MinGW...plus it was a surprise as i never thought of it that way (see post #2..lot of ppl don't know)... so i posted here to know if people do really make use of this in practice..
btw, Paul's comment on the need to over-allocate blocks was insightful too..
Re: dynamic array allocation
Hi. In addition to what others said, I'd just like to make a few points. In one of your posts, you were referring to Stroustrup's book. You've probably read this:
Quote:
To deallocate space allocated by new, delete and delete [] must be able to determine the size of the object allocated. This implies that an object allocated using the standard implementation of new will occupy slightly more space than a static object. Typically, one word is used to hold the object's size.
[Emphasis by me.]
Furthermore, in that article you've linked to:
Quote:
Here's how the Microsoft C++ compiler manages vector allocation. Note that this is internal implementation detail, so it's subject to change at any time, but knowing this may give a better insight into why mixing scalar and vector new/delete is a bad thing.
The important thing to note is that when you do a scalar "delete p", you are telling the compiler, "p points to a single object." [...]
When you do "delete[] p", you are saying, "p points to a bunch of objects, but I'm not telling you how many."
[Emphasis by me.]
So, these just reflect on how things work under the hood, but you should never rely on some specific implementation. And this recommendation goes beyond C++ syntax - when you write code that uses classes from a library, you shouldn't rely on the implementation details either, but on the public interface of the class instead. In a good design, the internal details will be hidden anyway.
Re: dynamic array allocation
I just found something for those who use VC++ and, despite all the good advice above, still want to mess around with implementation details: the _heapwalk() CRT function. :D
I rememberd having used that function back in the days of MS C 6.0 (without ++) under DOS and got curious whether it's still there. And although the MSDN documentation on that function is as of VC++ 6.0 it's actually still there in VC++ 2010.
The following is a modified version of the MSDN sample code from the _heapwalk() page. The main intention behind the modifications was to have the program use new [] and delete [] instead of malloc() and free(), and to enable it to identify the test object created during the demo, but there are some more minor modifications.
Code:
/* heapwalk.cpp: This program "walks" the heap, starting
* at the beginning (_pentry = NULL). It prints out each
* heap entry's use, location, and size. It also prints
* out information about the overall state of the heap as
* soon as _heapwalk returns a value other than _HEAPOK.
*/
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <new>
void heapdump(int *tocheck);
void main( void )
{
char *buffer;
heapdump(NULL);
if( (buffer = new(std::nothrow) char[59]) != NULL )
{
strcpy(buffer, "Test!");
heapdump((int *)buffer);
delete [] buffer;
}
heapdump(NULL);
}
void heapdump(int *tocheck)
{
_HEAPINFO hinfo;
int heapstatus;
int *lastentry = NULL;
hinfo._pentry = NULL;
while( ( heapstatus = _heapwalk( &hinfo ) ) == _HEAPOK )
{
if (lastentry && tocheck >= lastentry && tocheck < hinfo._pentry) {
// Place breakpoint here to inspect our object's heap block pointed to by lastentry
printf(" ***** Our object!");
}
printf( "\n%6s block at %Fp of size %8.8X",
( hinfo._useflag == _USEDENTRY ? "USED" : "FREE" ),
hinfo._pentry, hinfo._size );
lastentry = hinfo._pentry;
}
printf("\n");
switch( heapstatus )
{
case _HEAPEMPTY:
printf( "OK - empty heap\n" );
break;
case _HEAPEND:
printf( "OK - end of heap\n" );
break;
case _HEAPBADPTR:
printf( "ERROR - bad pointer to heap\n" );
break;
case _HEAPBADBEGIN:
printf( "ERROR - bad start of heap\n" );
break;
case _HEAPBADNODE:
printf( "ERROR - bad node in heap\n" );
break;
}
}
I think this could be used to actually find out about the size of objects allocated on the heap, but iterating over (at average) half the entire heap just to find out the size of some object (what appears to be the goal of the OP) would be terrible inefficient. Better simply use std::vector in the first place, as already suggested by (at least) Russco as far back as post #3 which would not only be considerably more efficient but also not relying on implementation details.
I think I should emphasize again that this CRT function is solely meant for diagnostic use.
From post #16 it looks as if the OP isn't using VC++, but I still wanted to post the result of my research for curious minds (like myself :D) in general.