Is it a good idea to replace the C-style POD array with std :: valarray?

I work with a code base that is poorly written and has a lot of memory leaks.

It uses many structures containing source pointers, which are mainly used as dynamic arrays.

Although structures are often passed between functions, the distribution and release of these pointers are placed in random places and cannot be easily tracked / justified / understood.

I changed some of them to classes, and those pointers that should be RAII are the classes themselves. They work well and do not look very ugly, except that I forbade copying and copying these classes simply because I do not want to waste time implementing them.

Now I think I'm reinventing the wheel again? Why can't I replace a C-style array with std: array or std :: valarray?

I would prefer std :: valarray because it uses heap and RAIIed memory. And std :: array is not yet available in my development environment.

Edit1 . Another plus of std :: array is that most of these dynamic arrays are POD arrays (mostly int16_t, int32_t and float), and the numerical API can make life easier.

Is there anything I should know about before I get started?

I might think that there might be a hard way to convert std :: valarray or std :: array into C-style arrays, and part of our code uses pointer arithmetic and needs to be presented as simple C-style arrays.

Anything else?

EDIT 2

I recently met this question . The VERY BAD thing about std::valarray is that it is not reliably assigned to copy before C ++ 11.

As indicated in this answer, in C ++ 03 and earlier, UB if the source and destination are of different sizes.

+6
source share
3 answers

The standard replacement for a C-style array will be std::vector . std::valarray is some kind of "strange" mathematical vector for working with numbers. It is not intended to store an array of arbitrary objects.

As they say, using std::vector is most likely a very good idea. It will fix your leaks, use a bunch, resize, has an excellent exception-security, etc.

It also ensures that data is stored in one contiguous block of memory. You can get a pointer to the specified block using the data() function or, if you are pre-C ++ 11, with &v[0] for a non-empty vector v . Then you can do your business of pointers with it, as usual.

+13
source

std::unique_ptr<int[]> is close to replacing the replacement for the int* owner. It has the good property that it does not implicitly copy itself, but it will implicitly move.

The copy operation generates compile-time errors, not runtimes.

In addition, he also has no unnecessary time spent on having int* , except for checking the zero level upon destruction. It uses no more space than int* .

std::vector<int> stores 3 pointers and implicit copies (which can be costly and doesn't match your existing code behavior).

I start with std::unique_ptr<int[]> as the first pass and get it working. I can translate some code to std::vector<int> after I decided that prudent buffer management is worth it.

In fact, as a first pass, I would look for memcpy and memset and similar functions, and make sure that they do not work on the structures in question before I start adding RAII members.

A std::unique_ptr<int[]> means that the default destructor for the structure will clear RAII without writing new code.

+6
source

I would prefer std::vector as a replacement for c-style arrays. You can have direct access to the underlying data (something like simple pointers) via .data() :

Returns a pointer to a base array that serves as a store for items.

+5
source

Source: https://habr.com/ru/post/981768/


All Articles