terminating with uncaught exception of type std::out_of_range: basic_string

Hello, I'm having an issue with this dummy program that I'm trying to use. I want the user to input a DNA strand and from there, the three functions are responsible for finding "ATG" (start codon), a stop codon ("TAA" in my case), and producing a substring.

For example, if I enter "TCAATGCGCGCTACCCGGAGCTCTGGGCCCAAATTTCATCCTAAACT", the output should be "ATGCGCGCTACCCGGAGCTCTGGGCCCAAATTTCATCCTAA". Each ORF function should search in triplets (codons). ORF1 should search TCA, ATG, etc. ORF2 should search CAA, TGC, etc. and ORF3 should search AAT, GCG, etc.

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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  #include <iostream>
#include <string>
#include <cctype>

using namespace std;

void ORFfinder1(string strand, string strand1); 
void ORFfinder2(string strand, string strand2); 
void ORFfinder3(string strand, string strand3); 

int main () {
	string strand, strand1, strand2, strand3;

	cout << "Enter a string: ";
	cin >> strand;

	ORFfinder1(strand, strand1); 
	ORFfinder2(strand, strand2); 
	ORFfinder3(strand, strand3);


	return 0;
}

void ORFfinder1(string strand, string strand1) {

	int pos, pos1;
	int size = strand.length();

	for (int i = 0; i < size; i = i + 3) {
		pos = strand.find("ATG", i); 
	}

	pos1 = strand.find("TAA");

	if (pos1 > 7) {
		strand1 = strand.substr(pos, pos1); 
		cout << strand1; 
	}

	else {
		cout << "Sorry, nothing found at reading frame 1." << endl;
	}
}

void ORFfinder2(string strand, string strand2) {

	int pos, pos1; 
	int size = strand.length();
	
	for (int i = 1; i < size; i = i + 3) {
		pos = strand.find("ATG", i); 
	} 

	pos1 = strand.find("TAA");

	if (pos1 > 7) {
		strand2 = strand.substr(pos, pos1); 
		cout << strand2; 
	}

	else {
		cout << "Sorry, nothing found at reading frame 2." << endl;
	}
}

void ORFfinder3(string strand, string strand3) {

	int pos, pos1; 
	int size = strand.length();
	
	for (int i = 2; i < size; i = i + 3) {
		pos = strand.find("ATG", i); 
	} 

	pos1 = strand.find("TAA");

	if (pos1 > 7) {
		strand3 = strand.substr(pos, pos1); 
		cout << strand3; 
	}

	else {
		cout << "Sorry, nothing found at reading frame 3." << endl;
	}
}

Last edited on
$ gdb a.out
(gdb) run
Enter a string: TCAATGCGCGCTACCCGGAGCTCTGGGCCCAAATTTCATCCTAAACT
terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::substr: __pos (which is 18446744073709551615) > this->size() (which is 47)

Program received signal SIGABRT, Aborted.
(gdb) backtrace
#0  0x00007ffff72414b7 in raise () from /usr/lib/libc.so.6
#1  0x00007ffff724288a in abort () from /usr/lib/libc.so.6
#2  0x00007ffff7b2cfcd in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/libstdc++.so.6
#3  0x00007ffff7b2ae56 in __cxxabiv1::__terminate(void (*)()) () from /usr/lib/libstdc++.so.6
#4  0x00007ffff7b2aea1 in std::terminate() () from /usr/lib/libstdc++.so.6
#5  0x00007ffff7b2b0b8 in __cxa_throw () from /usr/lib/libstdc++.so.6
#6  0x00007ffff7b84f31 in std::__throw_out_of_range_fmt(char const*, ...) () from /usr/lib/libstdc++.so.6
#7  0x00007ffff7b91032 in std::string::substr(unsigned long, unsigned long) const ()
   from /usr/lib/libstdc++.so.6
#8  0x0000000000400ffc in ORFfinder1 (strand="TCAATGCGCGCTACCCGGAGCTCTGGGCCCAAATTTCATCCTAAACT", strand1="")
    at foo.cpp:37
#9  0x0000000000400da7 in main () at foo.cpp:17
(gdb) frame 8
#8  0x0000000000400ffc in ORFfinder1 (strand="TCAATGCGCGCTACCCGGAGCTCTGGGCCCAAATTTCATCCTAAACT", strand1="")
    at foo.cpp:37
37			strand1 = strand.substr(pos, pos1); 
(gdb) info locals
pos = -1
pos1 = 41
size = 47
when trying to construct your substring it is accessing out of bounds.

72
73
74
for (int i = 2; i < size; i = i + 3) {
	pos = strand.find("ATG", i);
}
you are overwritting the results of the previous search, so you end with the value of the last one.
(which in this case fails and returns string::npos, -1)


Also, substr() ask for start position and lenght
Last edited on
Hi,

Just some minor details, in addition to ne555's expert advice:

Your variables strand1, strand2, strand3 are not initialised to anything. Even though you assign to them inside the function, I am just pointing this out because one day that will cause you a problem. A Golden Rule is to always initialise your variables - preferably at the same time as declaration, and do 1 declaration per line. I do it, even when I might assign a value from input on the next line.

Your 3 functions are very similar, can you figure out how to only have one function? The difference between them seems to only be the start position. If you find yourself writing similar code over and over, then there is a better way.

Try to avoid magic values like "TAA" and "ATG" and 7 in your code, these should be const variables instead.

You could mark your function parameter strand as const so that there is no risk in the function inadvertently changing the value of it.

To be picky, some of your variables should of type std::size_t.

Try to avoid using namespace std; Google to see why, and what to do instead.

Hope all goes well :+)
> Your variables strand1, strand2, strand3 are not initialised to anything
They are initialised to an empty string.

> Even though you assign to them inside the function
Haven't notice that.
Your prototype is void ORFfinder1(string strand, string strand1); however you don't care about the value of `strand1' ¿so why pass it as parameter?
You then modify that variable inside the function. That change would not be reflected in the variable in main, as the parameter is passed by value.
Topic archived. No new replies allowed.