Using C++11, I like to create an array of booleans and immediately clear it
bool *mymap = new bool[n];
n is variable.
Now, does this already clear the memory occupied by the array? If not, is there a better approach to clear the array than using a loop over all elements, setting each to false individually?
I considered using std:memset(), but that requires me to know the size of the array. Now, beginners might say: Easy, the size is n*sizeof(bool). But I don't buy that. The compiler might decide to pack them differently, even pack them as bits, couldn't it?
So, is there a way to tell the size of the array more cleanly? I imagine there might be a std:arraysize() function that simply returns the space of the allocated array in memory. After all, that information must be maintained at runtime somehow, or a delete invocation wouldn't know how much to release, right?
C does not store the size of the array - period. That is a fact of life. And, when an array is passed to a function, the size information is not passed to the function; the array 'decays' to a pointer to the zeroth element of the array - and only that pointer is passed.
How does free() know the size of memory to be deallocated? The free() function is used to deallocate memory while it is allocated using malloc(), calloc() and realloc(). The syntax of the free is simple. We simply use free with the pointer.
Arrays are static so you won't be able to change it's size. You'll need to create the linked list data structure.
The answer to the specific question is no, you cannot determine the length of the array pointed at by mymap
. The language simply provides no mechanism for that.
But if all you want to do is make sure that all the elements of the array are set to false
, then all you have to do is value initialize it:
bool* mymap = new bool[n]();
// ^^
Unfortunately, this only works for zero-like values for built-in types. There would be no equivalent way to set all the values to true
.
You cannot do it in a standard way. However, different compilers support different hacks to do it, for example:
#if defined(_MSC_VER) || ( defined(__GNUC__) && defined(_WIN32) )
// a dirty MSVC and MinGW hack
size_t Size = _msize( mymap );
#elif defined(__GNUC__)
// a dirty glibc hack
size_t Size = malloc_usable_size( mymap );
#else
#error Implement for any other compiler
#endif
But these are real hacks, so beware.
By the way, std::vector
can help you to solve your problem within the standard.
No you can't, because it's not actually an array. mymap
is just a normal pointer to some heap memory, and if you need to know the size you either have to keep track of it yourself or use a standard container such as std::vector
.
Oh, and if you want a more generic variant of memset
read about std::fill
.
No, the compiler can't decide to pack them except so that the size of the region is n * sizeof(bool)
- doing it any other way would break the ability to address individual array members as mymap[x]
(which is the same as *(mymap + x)
).
In this case, beginners' suggestion is the correct one.
You can try this:
bool *mymap = new bool[n] ();
However this sets to false
and you cannot use such a way to set to true
.
Let's assume that the compiler decides to pack differently.
Assumption 1: the compiler packs some bits together into one byte. If you take the address of a single element inside the array, it's of type bool. Since the compiler can not (in general) deduct what you will do with this address (e.g. passing it to a function which passes it to a lib, ...), bit-packing inside one byte can't really happen. Otherwise the compiler needs to mask the appropriate bit from its packed region and move it somewhere as a real bool.
Assumption 2: the compiler uses more than sizeof(bool) for one bool value. Highly unlikely - because then sizeof(bool) would simply be greater. Pointer-manipulations are still possible and in case of bit-arrays some other magic logic needs to be implemented.
Assumption 3: the compiler uses different sizes for the different fields of the array - even more unlikely. The administration information required is just too big.
From these 3 thoughts I'd say the simple solution is the best. Just to be sure for now and all the future of your program, write a small unit-test that tests exactly that (e.g. get the address of the first value, cast it to a pointer of a type that has the same sizeof as bool, calculate the address of element n, cast that address back to a pointer of bool, write something there and compare with the array access). Then you'll get a notification if something changes - but I doubt it will.
Sidenote - of course the compiler is always able to allocate more memory than required. But still, the array has that size (it's just placed in a larger chunk of memory).
In bare bone C++, no it is not possible. However you are encouraged (and really should) consider using a class to manage the memory anyway.
In C++98, you can either use a boost::scoped_array
or a std::vector
(though for bool
you might prefer a std::vector<char>
).
In C++11, you should consider replacing boost::scoped_array
by std::unique_ptr<bool[]>
.
The issue is until then, apart from std::vector
, none of those know the size of the array they contain; they just handle memory.
In C++14, a new contender appear: std::dynarray
. It's a trimmed down version of std::vector
whose size cannot be resized dynamically. In short, exactly what you want: just the array and its length, no overhead.
If your favorite compiler/toolchain does not support dynarray
yet you can easily implement it yourself:
template <typename T>
class dynarray {
public:
// methods go here.
private:
size_t size;
std::unique_ptr<T[]> array;
}; // class dyn_array
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With