Best format for changeable size array?

Hello
I'm making a program that hold a list of strings (commands) in memory, displays it with a GUI and also sends any of these strings to a USB port.
I'm thinking of holding the strings in a vector that is initialized in a class with methods to add or delete strings (commands).
Should I store these string in the vector or pointers to string? Or is there a better way?
Store the strings in a std::vector<std::string>. There is no better way.
Not that I have anything against using a vector but I would recommend using a list instead. Reason is because you want to delete if you want more speed as your data gets big a list will do the trick,
If you are adding items to the back of a sequence and removing them from the front, then the preferred container type is a deque (double-ended queue.) This supports almost identical functionalty as the vector, including random access. The exception is that it does not provide contiguous storage and can therefore not be used like a C-style buffer. And allows for fast inserts and removals from the front as well as the back of the sequence.

The list comes into its own when you need to remove and insert things from arbitrary positions in the sequence. But as it does not support random access.

A vector is good when you are adding and removing mainly from the end, and when the sequence it pretty much fixed. It supports random access and is the only one of the containers to guarantee contiguous storage.

(There is a school of thought that the deque should be the default choice of container; that you should only switch to vector when you need contiguous storage and list when you need to be able to insert and remove frequently from arbitrary positions in the sequence.)

Andy

PS Supporting information

A. Results from:

Analysis of List class uses
http://www.openoffice.org/tools/performance/list_classes.html

Operation            list  vector deque  OOo List 
    
Create 10000e        1762  231    126    1068
Delete 10000e        1513   22     56      12
Remove Front 10000e  1711  n/a     85    7975
Remove Back 10000e   1720   13     82    1064
Iteration 10000e       57   13     28      13

NOTE: all times are in u-seconds

(I'm not sure what the Ooo List class is; the Open Office guy's own list implementaton, I presume.)

B. Baptiste Wicht's performance benchmarks

C++ benchmark – std::vector VS std::list VS std::deque
http://www.baptiste-wicht.com/2012/12/cpp-benchmark-vector-list-deque/

C. Herb Sutter on why you should prefer deque

Using Vector and Deque
http://www.gotw.ca/gotw/054.htm
Last edited on
If the number of elements is small (say 500 integers or a 100 strings), always prefer std::vector<>

Erase in arbitrary positions is slow in a vector or a deque if and only if elements are removed one at a time, and the relative order of elements must be preserved. To remove a single element, swap with the back and pop_back in a vector or deque is faster than erase on a list. To remove multiple elements, the canonical std::remove_if/erase sequence on a vector or deque preserves the order and is faster than an equivalent operation on a list.

The primary advantages of a list are:
a. iterators and references to other elements are not invalidated by the insertions or removals.
b. list provides strong exception guarantees (commit-or-rollback) for some operations for which vector and deque provide only a weak guarantee (consistency).
These are the most common use-cases where a list would be a preferred choice.

Note: If performance is important for your program, measure it. Benchmarks involving hundreds of thousands of elements are completely irrelevant for use-cases where the numbers are much smaller. As always, prefer one measurement for your typical use-case over a thousand opinions.
Last edited on
Thanks. Vector seems the best choice.

But I have a problem with it, I get undeclared errors. Here's a little test code I tried:
header:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#pragma once
//#include "stdafx.h"
//#include <vector>
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
class ListofCommands
{
private:
	std::vector<std::string> commandsList; 
public:
	ListofCommands(void);
	~ListofCommands(void);
	void takeFromFile(void);
};


cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include "stdafx.h"
#include "ListofCommands.h"
/*#include <vector>
#include <iostream>
#include <fstream>
#include <string>*/

using namespace std;
//std::vector<std::string> commandsList; 
ListofCommands::ListofCommands(void)
{
	//std::vector<std::string> commandsList; 
	//commandsList.clear();
}


ListofCommands::~ListofCommands(void)
{
}

void takeFromFile(void)
{
	string line;
	ifstream myfile ("LIN_commands.txt");
	if (myfile.is_open())
	{
		while ( myfile.good() )
		{
			getline (myfile,line);
			//cout << line << endl;
			commandsList.push_back(line);
		}
		myfile.close();
	}
	else cout << "Unable to open file"; 
}


I get these errors:
Error	1	error C2065: 'commandsList' : undeclared identifier
Error	2	error C2228: left of '.push_back' must have class/struct/union
	3	IntelliSense: identifier "commandsList" is undefined

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// void takeFromFile(void)
void ListofCommands::takeFromFile()
{
   // ....
                // ....
   		// while ( myfile.good() ) // *** this is a wrong idiom
                while( getline( myfile, line ) ) // *** canonical
		{
			// getline (myfile,line); // *** wrong idiom
			//cout << line << endl;
			commandsList.push_back(line);
		}
                // ....
    // ...
}
1
2
3
4
void ListofCommands::takeFromFile(void)
{
    ...
}
Thanks
Amazing what stupid errors I can miss.
Topic archived. No new replies allowed.