String subscript out of range

I get this annoying error whenever I try to use either <string> or any STL container. Everyone I saw so far, says that "using a .reserve(n)" before adding items to random positions is enough. However, each time I run the code, I still get the same error, unless I actually write the memory with some initial data, and only after access random positions.
I am fully aware of the fact that the STL containers and <string> are dynamic data types and memory allocation is done dynamically. However, if I need to allocate all those memory slots before knowing how many I need, would lead me to the same memory complexity as using a char [] array (which is static -- size declaration at first).

My question is, how is it possible to keep the <string> dynamic, while being able to add elements on random positions (if possible). I know the strings have the ending char '\0', but there should still be something that would allow it to work. Okay, long story short, here is my example. I am trying to read from file rows of data. The first char on each row represents a normal char c. The rest of the row is a string which contains numbers (integers between 1 and 250) which represent the position at which the char c (read before) will have its location.

For example the input file:
  5 11
e 4 8 9 15
h 1 12
m 3 14
o 2 13
s 6
t 10
w 7


Would produce the following string:
home sweet home


Code:
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
37
38
39
40
41
42
43
44
45
#include <fstream>
#include <deque> // for later use
#include <string>
#include <sstream>
#include <algorithm> // for later use

using namespace std;

void readData(char &, string &, string &);
void solve(); // To be implemented once the actual problem is solved
void writeData(string);

int main(int argc, char *argv[]) {
	char chr;
	string input;
	string text;
	input.reserve(40);
	text.reserve(250);

	readData(chr, input, text);
	writeData(text);

	return 0;
}

void readData(char &chr, string &input, string &text) {
	int pos = 0;
	istringstream read;
	fstream in("text.in", ios::in);
	while (in.good()) {
		chr = in.get();
		getline(in, input);
		read = istringstream(input);
		while (read >> pos) {
			text[pos] = chr;  // Breaks here -- String subscript out of range
		} // I understand that what I'm doing is an illegal move, but how to fix it?
	}
	in.close();
}

void writeData(string text) {
	fstream out("text.out", ios::out);
	out << text << "\n";
	out.close();
}


Thanks in advance. If someone could explain this to me, like more in-depth (the idea of STL/String random memory allocation), I would be very grateful.

EDIT: The program works perfectly, if instead of text.reserve(250); I use text.resize(250);. However, could anyone point out the difference between the two? I mean, why isn't reserve enough?

Raul
Last edited on
The program works perfectly, if instead of text.reserve(250); I use text.resize(250);. However, could anyone point out the difference between the two? I mean, why isn't reserve enough?


text.reserve(250); simply tells the string to request allocate that memory, so that the container can grow to that size (if necessary) without having to allocate more memory. It does not actually change the size of the container. It does not create any new elements in the container.

text.resize() actually changes the size of the container, and causes new elements to be created.
Last edited on
reserve(x) is makes sure that there is enough memory allocated to hold at least x amount of elements that if in future container size changes up to x, it will guarantee that no reallocation will be made.
It changes container physical size (alolocated memory) but not logical size (number of elements)

resize(x) makes container logical size of x: destroying excess elements at the end or default constructing them if needed.
It changes logical size, increasing physical if needed.

Whoever said that "using a .reserve(n)" before adding items to random positions is enough" is plainly wrong.
Last edited on
Thank you very much for the explanation. Understood it now :)

Raul
Topic archived. No new replies allowed.