Reputation: 83
I'm messing around with arrays and attempting to find efficient ways of performing operations on the data.
Adding values at the end is easy enough but shifting the data on or more indexes back has drawbacks. I could potentially create an new array with sufficient space and copy the data starting at the shifted index and then delete the original and swap the pointers but I believe this method is memory inefficient.
I ended up stumbling upon utilizing memcpy() on the array itself assuming there's space in it for the shift and it worked beautifully, however I am concerned that it's not proper or if I'm doing the same thing only that not consciously.
My code looks like this
const int size = 25, buffer = 25;
int num[size+buffer]{};
initialize(num, size);
cout << "Values:" << endl;
print(num, size+buffer);
cout << endl << endl;
memcpy( &(num[size]), num, sizeof(int) * size );
cout << "Values:" << endl;
print(num, size + buffer);
cout << endl << endl;
initialize is a function to assign values from a file and its a simple for loop; By the second print function the array holds two copies of the values. If everything works as I think it is I'm thinking of shifting it the amount needed for the new values and then inserting them there. Seems clean and quick and hopefully memory efficient.
I would appreciate any feedback.
Upvotes: 2
Views: 1612
Reputation: 2573
You could probably implement it more efficiently by using a std::deque which is optimised to allow insertion and removal of items at the beginning and end. https://en.cppreference.com/w/cpp/container/deque
Although we could disappear down a bolt-hole in terms of algorithms etc, the nub of your question is, "is this considered bad practice". The answer to that is clearly "yes"; the modern philosophy is to write "expressive code". If you think that expressive code may be inefficient, and that working "close to the metal is best", check out Matt Godbolt's talk at CppCon 2017 in terms of how much optimisation compilers do for you. The message is clear; don't write "clever optimised code", just be clear and expressive about intent with the source, and let the compiler do the optimisation for you: https://www.youtube.com/watch?v=bSkpMdDe4g4
Another thing to consider is that a lot of algorithms are ranked according to Big O Notation
, which implies that some inefficient algorithms should never be used. However, some of the so-called inefficient algorithms are better in terms of locality of reference
; particularly if you're using small amounts of data that fits within a cache line. Linked lists will most likely jump around memory, leading to cache misses. Check out this presentation: https://www.youtube.com/watch?v=fHNmRkzxHWs
As suggested in the comments, also check out the following video about data structures (this link skips the first 8 minutes, because they are unimportant): https://youtu.be/4IrUAqYKjIA?t=525
Upvotes: 2
Reputation: 54325
You ought to just use std::vector
. If it is storing a POD (plain old data) type it will optimize to use memmove
. (Note: Using memcpy
as you are doing is not allowed on overlapping data. Things will break. When you least expect them.) And if it is storing a more complex type, it will do all of the proper extensions, copies, moves or swaps.
Upvotes: 0