at() not working in function - c++

I believe that I am doing everything right, but the string is not being filled with the characters it is assigned. Here is what I know by testing: random is the correct character, q is the correct int, and s[i].name is a string. I have tried using .at(q) and [q], but nothing is working.
This is my error:
terminate called after throwing an instance of 'std::out_of_range'
what(): basic_string::at
Abort (core dumped)
for (int i = 0; i < num; i++) {
int q = 0;
char random = 50;
for (; random != 32;) {
file.get(random);
s[i].name.at(q) = random;
q++;
}
q = 0;
}
cout << s[0].name;

If that's all the code, it's crashing because name isn't allocating memory anywhere. A call to at requires that there be at least that many elements already allocated for it to work. Try calling push_back instead, that will add the element at the back of the string, expanding it if necessary.
Also, the last line of the for is superfluous, no point in setting q to 0 since it gets destroyed the next line and a new q is allocated on the next loop. Not to mention that with push_back, keeping track of the index with q becomes entirely redundant.
Lastly, the for is making things unnecessarily complicated, use while in this case instead.

This is difficult, because you didn't give us complete code, but if I understand your intention, you should be able to get something like it with this:
for (int i = 0; i < num; i++) {
char random = 50;
s[i].name = "";
for (; random != 32;) {
file.get(random);
s[i].name += random;
}
}
cout << s[0].name;
If your string is too short, at() will throw an exception. Using concatenation like I did should handle arbitrarily large strings.

Related

c++ runtime error when 2d array assigning another array value

#include<iostream>
#include<string>
#include <cstring>
using namespace std;
bool b[200][200];
int a[46];
int test_cases;
int n;
int m;
int first;
int second;
int main()
{
cin>>test_cases;
while(test_cases--){
cin>>n;
cin>>m;
for (int i=0;i<2*m;i++){
cin>>a[i];
}
for (int j=0;j<m;j++){
first=a[2*j];
second=a[2*j+1];
b[first][second]=true;
}
}
return 0;
}
Hello. Runtime error seems to occur on the last code 'b[first][second]=true;'
I tried couple of changes and i found if i turn 'b[first][second]=true;' into 'b[second][first]=true;' error doesn't occur, which is simply to change the order of indices.
There is not a possibility of "out of range error" because memory size of b is [200][200] and range of results of a[*] is from 0 to 10.
I can't figure out where the problem is coming from and i need help. Thank you.
There is not a possibility of "out of range error" because memory size of b is [200][200] and range of results of a[*] is from 0 to 10.
The world is littered with buggy code because people made assumptions like this. The first thing you should do is prove this correct. That's as simple as placing something like:
if (first < 0 || first > 199 || second < 0 || second > 199) {
cerr << "Violation, first = " << first << ", second = " << second << "\n";
exit(1);
}
immediately before your line that sets the b[][] element to true.
As an aside, it would also be prudent to check other array accesses as well. Since we don't have your test data, we have no idea what value will be input for n or m but, since those values can result in undefined behaviour (by accessing beyond array bounds), they should also be scrutinised.
If you wanted to be sure that those didn't cause problems, you could dynamically allocate to the correct size as necessary. For example, once you've gotten m from the user:
int *a = new int[m*2];
// Use it as you wish, elements <0..m*2-1> inclusive.
delete [] a;

C++ program crashes on iterating till the last element of an array

I have the following code:
int main()
{
int a[5];
for (int i = 0; i <= 5; i++) {
cin >> a[i];
}
for (int i = 0; i <= 5; i++) {
cout << a[i] << endl;
}
}
The program is supposed to take 6 integers as input and just print them to the output. It works fine for the first five integers but crashes while printing the sixth. As far as I know, in c++ an array defined "a[5]" should have 6 elements since it starts from 0, right? What's causing the crash?
int a[5];
is an array of 5 integers! The indexing is 0, 1, 2, 3, 4.
The reason for this is how the elements live in memory. The index tells you how many spots to jump from the start of the array. So the first element, you have to jump 0 spaces, because it is at the very front of the array. The second element, you have to jump 1 space. Get it?
array start |data|data|data|data|data|<nothing here!>
offset from start | 0| 1| 2| 3| 4| not allowed!!
So by trying to jump into a position that doesn't actually exist in the array, you cause Undefined Behaviour. This means your program is garbage. There is no guarantee at all what might happen. It might crash, or worse, it might appear to work, because you actually hit some memory that is really being used to store a completely different object. Then you end up with some really crazy behaviour that is hard to debug.
A loop over an array should look like this:
for (size_t i = 0; i < arraySize; ++i) // ...
^ always <, never <=
But it is better to use std::vector, which will grow to the size you need, and manage all the memory for you. Then you can use myVector.at(3); to access the data, and it will throw an exception if you make a mistake like you did above. Or better, use the "range-based for loop", which will pull out all the elements for you:
#include <vector>
#include <iostream>
int main()
{
const std::size_t howMany = 6; // how many ints to read
std::vector<int> data;
while (data.size() < howMany) { // haven't read enough yet
int tmp = 0;
std::cin >> tmp;
if (!std::cin) { // somehow reading went wrong!
return 1; // exit the program with an error code
}
data.push_back(tmp); // store the value we just read
}
for (int i : data) { // go through all the stored ints
std::cout << i << '\n';
}
}
(Also, see here for some common beginner mistakes you are making).

C++ Add random characters into a string array

So I want to create 1000 words with a length of 5 random characters. In my main I have word[1000] but when I try to run this code, it gives me an error saying "Expression:string subscript out of range". I'm not sure why it does that because I thought string arrays were 2 dimensional? If anyone could tell me why my code is wrong I'd appreciate it. Thanks.
void createText(string w[], int seed) {
char ch;
srand(seed);
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 5; j++) {
ch = ('A' + rand() % 26);
w[i][j] = ch;
}
}
for(int i = 0; i < 1000; i++) {
cout << w[i];
}
cout << endl;
}
I suppose that the array w does not have 1000 elements, also remember that here you will get a copy of string w[]. Better would be passing a pointer to w (string* w), then You will have very clearly what is wrong. remember also that cout writes the string out untill it reaches a '\0' character, this also might be the cause. Quick session with gdb will help:
gdb program
...
run
bt full
should pinpoint Your problem. if it's some kind of IDE, learn how to debug in it. Valgrind or some other memcheck like visual leak detector or luke stackwalker will also show you some tips about bad initialization or unmentioned memory leaks.
If an array is bidimensional, you can't print its values like w[i]. You must print always keeping in mind that the array is bidimensional, which means that the output must be done like cout << w[i][j];
In addition, you're passing an array of strings as an argument, and what you're doing is add characters to every single position, which means that you won't actually have nothing but 1000 characters inserted into that string (because you actually added "one-char" strings), so you'll only put 200 words with a length of 5 characters each one. Insert strings directly, and you'll get your 1000 words, but first find a way to build strings with random characters.
Something like:
for(conditions){
for(conditions){
build a word
}
array[x][y] = string
}
I guess it is similar to what you intended to do

Read from string (possible array usage?) C++

I'm attempting to write alil function here which basically reads from a string. It reads every three characters and evaluates it using the pre-condition (if statement). If conditions are met, it would replace those three letters with new three letters. Then it would output the new string.
I tried writing the code but cant seem to get the logic right. the program runs but it doesn't print out anything. Dont mind the function name and the inaccuracy. I'm just doing a sample function to test this out.
string amino_acids(string line)
{
string acid;
string acids;
string newline;
for( int i= 0; i < line.length(); i++)
{
acid = line[i];
}
for (int i = 0; i < 3; i++)
{
acids = acid[i];
if(acids == "GUU")
{
acids = "ZAP";
}
newline = acids;
}
cout << "Acids: " <<newline <<endl;
return newline;
}
for( int i= 0; i < line.length(); i++)
acid = line[i];
Say line contains "abcd", this loop is going to do:
acid = 'a';
acid = 'b';
acid = 'c';
acid = 'd';
Only the last assignment has any lasting affect. If you need to actually get three characters from line into acid - you probably want to use += to add characters into acid, rather than =. But, if you loop over all of line like this, you'll end up doing acid = line;. I assume you want something more like acid = line.substr(0, 3)?
for (int i = 0; i < 3; i++)
{
acids = acid[i];
This is going to crash. acid is definitely a single character string, and you're indexing into acid[1] and acid[2] on the 2nd and 3rd iterations. While you're learning C++, you should probably use .at(i) which will throw an exception when you attempt to use an invalid index - you can catch the exception and at least have some indication of the problem. As is, it's undefined behaviour.
To use at, you need a try / catch block... the basic form is:
int main()
try
{
...your code in here...
some_string.at(i);
}
catch (const std::exception& e)
{
std::cerr << "caught exception: " << e.what() << '\n';
}
More generally, try putting some std::cout statements throughout your code so you know what values your variables actually have... you would easily have seen that they weren't what you expected. Alternatively, use an interactive debugger and watch the affect of each statement's execution.
Indexing a std::string with the [] operator yields a char, for which there just happens to be an overloaded operator= for strings.
Even if you were looping as I believe you intended (which, as the comments on the question mention, you probably aren't) because acids (which takes the value of a single character) will never be equal to the three character string you're comparing it to. Thus, no replacements will be performed.
To do what you want, try something like this:
for (int i = 0; i + 3 < line.length(); i += 3) // counting by 3 until end of line
{
if (line.substr(i, 3) == "GUU") // if the substring matches
{
line.assign("ZAP", i, 3); // overwrite it with new substring
}
}
return line;
Reading from your description, you want something like so
//note below does not compile, its just psuedo-code
string amino_acid(const string& sequence){
string result = sequence; //make copy of original sequence
For i = 0 to sequence.length - 3
string next3Seq = sequence(i,3); //grab next 3 character from current index
If next3Seq == 'GUU' //if the next next three sequence is 'GUU'
then result.replace(i,3,'ZAP'); //replace 'GUU' with 'ZAP'
EndIf
EndFor
return result;
}
You can use that as a start to code. Good Luck.
According to my understanding of your question. I have written some code. Please look below
string acids;
string newLine;
int limit=1;
for(int i=0;i<line.length();i++)
{
acids=acids+line[i];
if(limit==3)//Every 3 characters
{
if(acids == "GUU")
{
acids = "ZAP";
}
limit=1;
acids=""
newline=newline+acids;
}
limit++;
return newline;
}

segmentation fault when calling a function

Segmentation fault when calling the Update_Multiplier and gdb debugger shows these:
Program received signal SIGSEGV, Segmentation fault.
0x080b74e8 in Update_Multiplier() ()
double upperbound = 116325;
double objective = 1.1707e+07;
int main()
{
Update_Multiplier();
}
void Update_Multiplier()
{
cout << "function 0" << endl;
// Determine subgradient vectors
double gra[1000][1000];
double grb[1000][1000];
double dumX = 0;
double stepsize[1000][1000];
double tuning=2;
double LRADum[1000][1000];
double LRBDum[1000][1000];
cout << "function 1" << endl;
// update subgradient vectors
for (int i=1; i<=noOfNodes; i++)
{
for (int j=1; j<=noOfNodes; j++)
{
if (C[i][j] != 0)
{
dumX=0;
for (int p=1; p<=noOfCommodity; p++)
{
dumX += X[i][j][p];
}
gra[i][j]=dumX-U[i][j]*Y[i][j]-Q[i][j];
grb[i][j]=Q[i][j]-B[i][j]*Y[i][j];
}
}
}
// update stepsize
cout << "function 2" << endl;
for (int i=1; i<=noOfNodes; i++)
{
for (int j=1; j<=noOfNodes; j++)
{
if (C[i][j] != 0)
{
stepsize[i][j]=(tuning*(UpperBound-Objective))/sqrt((gra[i][j]*gra[i][j])*(grb[i][j]*grb[i][j]));
LRADum[i][j]=LRA[i][j]+stepsize[i][j]*gra[i][j];
LRA[i][j]=LRADum[i][j];
LRBDum[i][j]=LRB[i][j]+stepsize[i][j]*grb[i][j];
LRB[i][j]=LRBDum[i][j];
}
}
}
}
I see two suspicious things in your code.
First, you are taking too much stack space (about ~40 MB).
Second, you are starting the index of the array at 1, where it should be 0:
for (int i=1; i<=noOfNodes; i++)
Change it to:
for (int i=0; i<noOfNodes; i++)
At a guess, you have a stack overflow! You cannot reliably create gigantic arrays on the stack. You need to create them dynamically or statically.
Where did you define noOfNodes? What is the initial value of this? Or, do you read this in from the console? If this is uninitialized, it probably has junk data -- which may or may not explain the crash.
You need a stack of at least 40 megabytes to run this function because you're allocating five arrays of one million eight-byte doubles each.
Change the function to allocate the double arrays from the heap using new.
You should really give us the whole code, e.g. noOfNodes is not defined anywhere.
Just a stab in the dark: are you possibly overflowing C since your indices (i and j) go from 1 to noOfNodes?
First, what Neil said is true.
Second, C and C++ arrays start from index zero. If you declare
int a[100]; // 100 elements, from zeroth to ninety-ninth.
Then its elements are a[0], a[1] ... a[99].
I can not see anything wrong with this code as given, BUT: You might have an off-by-one error if noOfNodes is 1000.
Remember that Arrays are 0-indexed so you have to access indexes 0 - 999 instead of 1 - 1000 as you are doing
me too i have this problem and my function returned std::string now i just do reference an dreturn type void like that:
void readOnDicoFile(std::ifstream file/*If you have "using namespace std;" instruction, put ifstream, not std::ifstream (you can put both)*/)
and before:
std::string readOnDicoFile(std::string fileName/*If you have "using namespace std;" instruction, put ifstream, not std::ifstream (you can put both)*/)