3

Why use a new memory location like this when we have vectors?
Are there any Advantages?

bool* arr = new bool(size);

I am not clear what this line does but what I feel is this std::memset sets whatever param2 is given over all locations starting from address at param1 and ends at the given size

std::memset(arr, 0, sizeof(bool) * (num+1));
101010
  • 41,839
  • 11
  • 94
  • 168
  • 1
    Your title and content doesn't match, please clarify what are you trying to do. – Tatsuyuki Ishi Mar 12 '17 at 10:25
  • 4
    bool* arr = new bool(size); is not an array. – Venom Mar 12 '17 at 10:37
  • Really sorry I am new to c++ programming, is the bool* arr = new bool(size); not creating a contiguos space? – Ramachandra jr Mar 12 '17 at 10:39
  • 1
    the correct form would be using square brakets [ ] to create an array see link http://www.cplusplus.com/doc/tutorial/arrays/ – Venom Mar 12 '17 at 10:40
  • https://gist.github.com/anonymous/524357a70fc95b537f31f5d7ec3e8bb8#file-sieve-cpp-L12, I am learning this. – Ramachandra jr Mar 12 '17 at 10:41
  • @basslo that part I know, I am studying an algorithm that has the above lines and actually when the concept was being explained, it was explained as an array will hold all the numbers... so I assumed(like an array) it is a contiguos space – Ramachandra jr Mar 12 '17 at 10:43
  • `bool *arr = new bool(size)` dynamically allocates a single `bool`, and initialises that `bool` using `size`. The result of the initialisation depends on what `size` is. If it is of a type that can't be implicitly converted to `bool`, the result is a compilation error. If you want to dynamically allocate an array and `size` is of integral type, use `bool * arr = new bool[size]` (square brackets). – Peter Mar 12 '17 at 10:48
  • @Peter So if something has a size that is more size than a mem block to hold a single value, wouldn't that be (kind of) an array? – Ramachandra jr Mar 12 '17 at 10:55
  • it is important to understand the similarity between array and pointer arr[5] is equivalent to *(arr+5) for example. You can always write beyound your array size but this can be very dangerous (undefined behavior). – Venom Mar 12 '17 at 11:00
  • Because `std::vector` uses special packing people often avoid it. You can simply use `std::vector` as a `'bool'` *array* which keeps the advantages of using a `std::vector`. (`bool` is actually implemented as a `char`) – Galik Mar 12 '17 at 11:10
  • the problem that std::vector occupies more memory than std::vector since std::vector is optimized so every element doesn't occupy a byte but a bit. – Venom Mar 12 '17 at 11:15

2 Answers2

4

Why use a new memory location like this when we have vectors?

We cannot kow why the author used new here. The idiomatic way would be to use a std::vector<bool>

Are there any Advantages?

Usually not, but particularly std::vector<bool> is problematic because there is a specialization that doesn't work as for other types.

There are many questions like this on SO:

I am not clear what this line does but what I feel ...

Your guts are right.


Note: The code to allocate a contiguous array of bools with new would be

bool* arr = new bool[size];

Instead of a raw pointer you can use a smart pointer to allocate the array and don't need to care about the delete []:

std::unique_ptr<bool[]> arr{new bool[size]};
Community
  • 1
  • 1
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • Would `std::array` be better if `size` is known? – Ed Heal Mar 12 '17 at 10:45
  • @EdHeal Probably yes. – πάντα ῥεῖ Mar 12 '17 at 10:46
  • Yes totally right author'd used an array if the size was known, but in the algorithm that I am studying https://gist.github.com/anonymous/524357a70fc95b537f31f5d7ec3e8bb8#file-sieve-cpp-L12 the size of the array is decided by the user's input. FYI the link is a part of the whole actual file typed in by me – Ramachandra jr Mar 12 '17 at 10:51
  • @πάντα-ῥεῖ didn't understand this: __particularly std::vector is problematic because there is a specialization that doesn't work as for other types.__ – Ramachandra jr Mar 12 '17 at 10:57
  • @Ramachandrajr I'll add a link. – πάντα ῥεῖ Mar 12 '17 at 11:00
  • @πάντα-ῥεῖ Your guts are right. :p thanks for that bro! – Ramachandra jr Mar 12 '17 at 11:02
  • @πάντα-ῥεῖ thanks for the link, from the link I understood that putting t/f (1/0) straight out using vector could cause memory related problems like the computer may think of it as a different piece of data rather than a straight out vector, so It's better to use 'new' and make use of heap vs other vector, deque options. Thanks a loooot! – Ramachandra jr Mar 12 '17 at 11:28
  • @Ramachandrajr With c++17 the `bool` array can be created with [smart pointers](http://en.cppreference.com/w/cpp/memory) that one no longer has to struggle with the corresponding `delete[]`. – πάντα ῥεῖ Mar 12 '17 at 11:30
  • @πάντα-ῥεῖ Thanks for the tip bro, will be using smart pointers from now on – Ramachandra jr Mar 12 '17 at 11:35
3

What this line bool* arr = new bool(size); does?

This line allocates a boolean in the heap and it initializes it to true if size != 0 and to false if size == 0. It then assigns the address of the newly allocated boolean to the boolean pointer arr. So no arrays in to play here.

How I could allocate an array of boolean with new?

The proper way to allocate an array in the heap is to use operator new[]. That is in your case:

bool* arr = new bool[size];

With the advent of smart pointers you could also use std::unique_ptr:

std::unique_ptr<bool[]> arr(new bool[size]);

Thus, you wouldn't have to delete [] afterwards.

Why use a new memory allocation like this when we have vectors?

Well with any other type except bool I would agree but the thing is that there are certain issues with std::vector<bool>.

std::vector<bool> is a specialisation of std::vector<T> that's done mainly for space efficiency (debatable).

However, it behaves similarly but not equally as a regular std::vector<T>. This is attributed mainly to the fact that std::vector<bool> is not a container in the usual STL sense but rather an array of bits. Generaly, use of std::vector<bool> can cause many havocs it's considered a premature optimization and it can even pessimize your performance (see more details here).

Another thing is that in embeded systems that space is crusial, using a raw array instead of a vector is a better option in terms of space efficiency.

What about std::memset(arr, 0, sizeof(bool) * (size));?

std::memset initializes a certain number of bytes in memory (i.e., third input argument) with a given value (i.e., second input argument) starting from address arr (i.e., first input argument). In the example above it will fill arr with 0s up to size number of bytes. That is if arr is an array of size size it will initialize all the elements of this boolean array to false.

However alternatevely, you could use the following scheme:

bool* arr = new bool[size]();
                          ^^

or

std::unique_ptr<bool[]> arr(new bool[size]());

And thus avoid calls to raw memory manipulators a std::memset that fall in the use with caution category.

Community
  • 1
  • 1
101010
  • 41,839
  • 11
  • 94
  • 168
  • wow, your answer is cool, but can't upvote :p I don't have enough points. Points taken: 1. new bool(size) <- size variable here is misleading and this is just used to create a single memory instance with t/f. 2. This alg's author simply cleared up the folowing memory space directly by allocating zero's doing suc thing is bad!!, but I think as it the heap's leftover mem, he/she didn't bother, stacks mem would have been disaster. 3. Have to use smart pointers to create such stuff. – Ramachandra jr Mar 12 '17 at 11:23