473,405 Members | 2,160 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Yet another thought about STL Vector

2
Hi. Let's see this:

std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
vec.push_back(4);
cout << vec[0]; // should display 1

std::vector<index>::iterator i = vec.begin();
vec.erase(i);
cout << vec[0]; // should display 2

I was thinking about how this is implemented in STL. The first thing that did strike me was this: (in a simple way, we all know STL is not exactly like this, it's just a way I found to reproduce the same behaviour)

int *vec = new int[4];
vec[0] = 1;
vec[1] = 2;
vec[2] = 3;
vec[3] = 4;
cout << vec[0]; // should display 1

memcpy( vec[0], vec[1], 3 );
cout << vec[0]; // should display 2

Ok. All this to ask you how STL implements the erase. It's known that it actually does not erase anything. Does it copy the "following" data if you "erase" something in the middle of it with an iterator? For it could be way slow, say, in a very large vector.

Hope my question was exposed clearly.
Any thoughts will be appreciated.
Jan 20 '09 #1
7 2626
newb16
687 512MB
It calls N assignment operators for vector elements ( N is distance from end() to iterator in erase() argument ) and one destructor ( applied to the last element )
Jan 20 '09 #2
JosAH
11,448 Expert 8TB
@dgmdgm
A small nitpick: note that this doesn't necessarily work; for overlapping memory regions memcpy may not do what you expect it to do. Use the memmove() function here. It all depends on the copying order used by memcpy().

kind regards,

Jos
Jan 20 '09 #3
Banfa
9,065 Expert Mod 8TB
The basic premiss of your argument, that you could end up doing a lot of copying in a vector making it in-efficient is basically true.

The vector is meant to be a drop in replacement for an array, including maintaining the same structure in memory. Because of this any erase or insert operation on a vector is bound to involve copying some of the vector and even adding data to the end of a vector will involve copying if the vector does not already have enough memory to hold all the data.

For this reason you would really only want to use a vector in a situation where the data held was relatively static and when filling a vector it is worth making the function call that sets its size before putting all the individual values into it.
Jan 20 '09 #4
emibt08
25
I wouldn't implement the vector as an array. At least not as you suggested. That way, it will have very poor performance, being just an array. If it actually is implemented that way, it would also need an internal table to keep track of the memory locations and gain performance that way.
So then, i believe that the most effective way to implement it would be as a linked list (double-linked list to allow for backward-iteration). It would have an overhead, of course, but the performance comes with a price, and in this case it's well worth it.
For example if you have a double linked list of integers, you'll need a structure with the actual element of type int and 2 pointers to integer (which in this case will have the same size as int, 4 bytes), leading to use of 12 bytes per element instead of 4. But then suppose you have a large number of elements (maybe 10000) and you want to erase any of it, you wouldn't need to move a single piece of allocated memory, nor to copy. You can just reconnect the nodes of the list and delete the allocated memory for that element. That way you gain a lot in performance/speed. And not to mention that if in the vector you have elements with larger size (perhaps some struct/class, not a primitive type), then the size of the head/tail in the list won't be much of an overhead compared to the overall size. It always will be an overhead, but that's the trade off.
If you don't want any memory overhead, the only solution would be as you suggested with the array, and then do memory reallocation (which in a larger application won't be feasible).

Another thing that i saw in your code was:
Expand|Select|Wrap|Line Numbers
  1. memcpy( vec[0], vec[1], 3 );
  2. cout << vec[0]; // should display 2
  3.  
One thing is that as JosAH suggested, memmove() might be a better solution. I don't think that memset() wouldn't work, since there is not a memory overlap. After all, vec[0] and vec[1] are different objects of same size, no matter if they are next to each other or not.
But why use 3 as a third parameter??? The size of int is 4, not 3. So, in your example it will work, but that's just a coincinence, because you're copying the 1st 3 bytes, leaving the MSB unchanged. If you wanna check it out, try with this:

Expand|Select|Wrap|Line Numbers
  1. vec[0] = 0x11223344;
  2. vec[1] = 0x55667788;
  3. memcpy( vec[0], vec[1], 3 );
  4.  
If you think that that code will make the value of vec[0] to be 0x55667788, well... think again. It will be: 0x11667788.

However, when using those functions, it would be safer to put sizeof(int) or sizeof(vec[0]) as a third parameter.

Cheers
Jan 20 '09 #5
JosAH
11,448 Expert 8TB
The STL also implements the 'list'. Lists and vectors are good at different things: if you want fast direct access (using a simple index), use a vector, if you want cheap element removal, use a list.

kind regards,

Jos
Jan 20 '09 #6
dgmdgm
2
Thank you all for your thoughts.
And, my bad, the memcpy should be:
Expand|Select|Wrap|Line Numbers
  1. memcpy( vec[0], vec[1], 3*sizeof(int) );
"Copy the next three 'ints'".
Sorry for that, it was a quick "in brownser coding" in order to explain my point.

And I think it is just like Banfa said, vector having the same structure in memory as an array, and the high price of removing an item in "the middle".
Jan 21 '09 #7
weaknessforcats
9,208 Expert Mod 8TB
Personally, I wouldn't use any mem... functions in C++. Little problems about copy constructors or assignment operators beign ignored producing a result batch of improperly initialized objects.

vector is an array. If you need to remove elements from a vector you can't do it easily without a lot of copying stuff. Instead, create a vector of struct variables where a bool in the struct determines whether the element is active or not. You delete an element just by setting the bool to inactive. Then your code that uses this vector just takes that into account.

Next, actual deleting would be better accomplished using a list or some other node-based container rather than a vector.
Jan 21 '09 #8

Sign in to post your reply or Sign up for a free account.

Similar topics

9
by: {AGUT2}=IWIK= | last post by:
Hello all, It's my fisrt post here and I am feeling a little stupid here, so go easy.. :) (Oh, and I've spent _hours_ searching...) I am desperately trying to read in an ASCII...
3
by: cheeser | last post by:
Hello, I'm trying to size a vector of vectors of unsigned ints to be an NxN square. Here's how I'm doing it: typedef vector<vector<unsigned int> > tournament_type; unsigned int n;
9
by: luigi | last post by:
Hi, I am trying to speed up the perfomance of stl vector by allocating/deallocating blocks of memory manually. one version of the code crashes when I try to free the memory. The other version...
7
by: Forecast | last post by:
I run the following code in UNIX compiled by g++ 3.3.2 successfully. : // proj2.cc: returns a dynamic vector and prints out at main~~ : // : #include <iostream> : #include <vector> : : using...
2
by: Pepijn Kenter | last post by:
Dear experts. I have a vector<float> and want to convert that to a vector<double>. I optimistically tried: #include <vector> #include <iostream> using namespace std; int main() {
34
by: Adam Hartshorne | last post by:
Hi All, I have the following problem, and I would be extremely grateful if somebody would be kind enough to suggest an efficient solution to it. I create an instance of a Class A, and...
8
by: Ross A. Finlayson | last post by:
I'm trying to write some C code, but I want to use C++'s std::vector. Indeed, if the code is compiled as C++, I want the container to actually be std::vector, in this case of a collection of value...
16
by: Martin Jørgensen | last post by:
Hi, I get this using g++: main.cpp:9: error: new types may not be defined in a return type main.cpp:9: note: (perhaps a semicolon is missing after the definition of 'vector') main.cpp:9:...
24
by: toton | last post by:
Hi, I want to have a vector like class with some additional functionality (cosmetic one). So can I inherit a vector class to add the addition function like, CorresVector : public...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.