Abort signal from abort(3) (SIGABRT) in C++ - c++

#include <iostream>
using namespace std;
int main()
{
//code
int test;
cin >> test;
while(test--)
{
int count = 0;
string input;
cin >> input;
for (int j = 0; j < input.length() - 2; j++)
{
if (input.substr(j, 3) == "gfg")
{
count +=1;
}
}
if (count > 0)
{
cout << count << endl;
}
else
{
cout << -1 << endl;
}
}
return 0;
}
This code shows Abort signal from abort(3) (SIGABRT) while submitting in Geeks for Geeks while runs perfectly on the local computer and even works perfectly on various online compilers. Can't figure out the problem. Can someone help?

Think about what happens when input has fewer than two characters.
input.length() is an unsigned quantity, so input.length() - 2 then would wrap around to an astronomically large number.
input.substr(j, 3) isn't good when j is an astronomically large number: it throws the exception std::out_of_range; since you're not catching this exception, your program terminates.
These contests test to see whether you cover all your possible input domains, especially edge cases. Be sure to consider them when you write your algorithm.

Related

How Do I Code a Contact List Program in C++ Using Functions & Vectors?

I am trying to write a contact list program in the C++ programming language and I think I have a good base set up for one. The premise of the program is that two vectors of values are entered. One vector for the contact name and another for the phone number. Once a few of these values are taken in by the program, a single contact name is supposed to signify to the program that its corresponding phone number should be outputted.
(Note: The '3' is supposed to tell the program how many values are to be stored in each vector. In this case, it is 3 contact names and 3 phone numbers.)
Ex. Input: 3 Joe 123-5432 Linda 983-4123 Frank 867-5309 Frank
Ex. Output: 867-5309
But I am getting an error message that reads, "Exited with return code -11 (SIGSEGV)." I'm not sure where I could be leaking any memory but maybe I just can't see it.
Any help that can fix this error would be greatly appreciated.
Below is code that I have written so far:
#include <iostream>
#include <vector>
using namespace std;
string GetPhoneNumber(vector<string> nameVec, vector<string> phoneNumberVec, string contactName) {
string theName;
string thePhoneNum;
string theContName;
int N;
int nElements;
cin >> N;
cin >> theName;
cin >> thePhoneNum;
cin >> theName;
cin >> thePhoneNum;
cin >> theName;
cin >> thePhoneNum;
nameVec.push_back(theName);
phoneNumberVec.push_back(thePhoneNum);
cin >> contactName;
nElements = phoneNumberVec.size();
for (int i = 0; i < nElements; i++) {
if (i == N) {
return phoneNumberVec.at(i);
}
}
}
int main() {
vector<string> nameVec;
vector<string> phoneNumberVec;
string contactName;
cout << GetPhoneNumber(nameVec, phoneNumberVec, contactName) << endl;
return 0;
}
The issue is that you are supposed to return a std::string from GetPhoneNumber, but there are code paths where no return is specified.
What happens is that the program has now invoked undefined behavior, as returning no value from a function that's supposed to return a value leads to undefined behavior occurring.
The fix is to return a std::string from the GetPhoneNumber function from all code paths. Namely right here:
for (int i = 0; i < nElements; i++) {
if (i == N) {
return phoneNumberVec.at(i);
}
}
return ""; // or some appropriate string.
}
To prove that this is the issue, if you do not have that return statement, and instead did this:
for (int i = 0; i < nElements; i++) {
if (i == N) {
return phoneNumberVec.at(i);
}
}
std::cout << "There will be a problem" << std::endl;
}
You will see the string,
There will be a problem
outputted, proving you are reaching that point in the function without returning a value.
Here is a live example.
The other issue is that i could never equal N, since a std::vector uses 0-based indexing. If N is 1, then the highest index for i will be 0.
The fix is to compare i to N-1.

C++ Sorting Players

Several people are playing a game. Every player has a certain individual number of victories and losses (which might be equal or different). Write a program that prints the name and final result of each of them,.
Note: If there is a player with multiple attempts, the victories and losses are added to the final result.
Input
• Until you receive the string "End", you are given the players’ information in the following order:
- Name: string
- Victories: a positive integer
- Losses: a positive integer
using namespace std;
int main() {
char str[100][20], t[20];
int i, j;
int n;
cin >> n;
int first[100];
int second[100];
for (i = 0; i < n; i++) {
cout << " ";
cin >> str[i];
cin >> first[i];
cin >> second[i];
}
for (i = 1; i < n; i++) {
for (j = 1; j < n; j++) {
if (strcmp(str[j - 1], str[j]) > 0) {
strcpy_s(t, str[j - 1]);
strcpy_s(str[j - 1], str[j]);
strcpy_s(str[j], t);
}
}
}
// cout << "\n Names Sorted in Alphabetical Order : \n\n";
for (i = 0; i < n; i++) {
cout << " ";
cout << str[i] << endl;
cout << first[i] - second[i] << endl;
}
return 0;
}
First, Your choice of data structures is questionable. You essentially have three arrays, side by side by side, that must all be maintained together when modifying the "order" of any one of them. That is the crucial piece of logic missing in your code.
Second, you're utilizing none of the standard C++ library, save for IO operations. Although this can compile, and may even work, you're not fulfilling a key attribute of an arbitrary number of entries. You code assumes the first input is a count of players. Nowhere in the problem description is that assumption validated. You should be reading name,victories,losses as a trio continuously until "End" is read for the name and/or you reach eof on stdin (the latter is assumed but safely so). Dynamic storage is required, and the C++ standard library as a multitude of containers available to make that possible, the most common being std::vector
#include <iostream>
#include <vector>
#include <string>
#include <utility>
int main()
{
std::vector< std::string > names;
std::vector< int > wins;
std::vector< int > losses;
std::string name;
int win;
int loss;
while (std::cin >> name && (name != "End") && std::cin >> win >> loss)
{
names.emplace_back(name);
wins.emplace_back(win);
losses.emplace_back(loss);
}
size_t len = names.size();
while (len-- > 0)
{
for (size_t j = 0; j < len; ++j)
{
if (names[j + 1] < names[j])
{
// swap all three arrays
std::swap(names[j + 1], names[j]);
std::swap(wins[j + 1], wins[j]);
std::swap(losses[j + 1], losses[j]);
}
}
}
std::cout << "Names Sorted in Alphabetical Order:\n";
for (size_t i = 0; i < names.size(); ++i)
{
std::cout << names[i] << '\n';
std::cout << wins[i] - losses[i] << '\n';
}
return 0;
}
Note, this is incredibly non-maintainable. As more and more information is associated with each name (not just wins and losses, but perhaps home address, telephone number, playing style or position etc.) maintaining yet more arrays becomes a nightmare. Rather, you opt for an object to host all player information, and single container that holds instances of that object. No doubt you'll be learning more on that in your studies.
But in the meantime, the code above complies with the problem statement, while addressing the key piece of logic missing in your posted code. If you're going to swap names during sorting, you have to swap win/loss records as well, so the player in some arbitrary position n has their wins/losses come along for the ride.
No wonder that someone will whine that it is a homework comment and not to help.
AJod Accrd i think that you need to do a public class and then do a map of string and pair of 2 integers

Super basic code: Why is my loop not breaking?

for(int i=0;i<50;i++,size++)
{
cin >> inputnum[i];
cout << size;
if(inputnum[i] == '.')
{
break;
}
}
The break breaks the input stream but the size keeps outputting.
The output of size is 012345678910111213...474849.
I tried putting size++ inside the loop but it made no difference. And size afterwards will be equal to 50, which means it went through the full loop.
I forgot to explain that I added the cout << size within the loop to debug/check why it outputted to 50 after the loop even if I only inputted 3 numbers.
I suspect that inputnum is an array of int (or some other numeric type). When you try to input '.', nothing actually goes into inputnum[i] - the cin >> inputnum[i] expression actually fails and puts cin into a failed state.
So, inputnum[i] is not changed when inputting a '.' character, and the break never gets executed.
Here's an slightly modified version of your code in a small, complete program that demonstrates using !cin.good() to break out of the input loop:
#include <iostream>
#include <ostream>
using namespace std;
int main()
{
int inputnum[50];
int size = 0;
for(int i=0;i<50;i++,size++)
{
cin >> inputnum[i];
if (!cin.good()) {
break;
}
}
cout << "size is " << size << endl;
cout << "And the results are:" << endl;
for (int i = 0; i < size; ++i) {
cout << "inputnum[" << i << "] == " << inputnum[i] << endl;
}
return 0;
}
This program will collect input into the inputnum[] array until it hits EOF or an invalid input.
What is inputnum ? Make sure t's a char[]!! with clang++ this compiles and works perfectly:
#include <iostream>
int main() {
int size = 0;
char inputnum[60];
for(int i=0;i<50;i++,size++) {
std::cin >> inputnum[i];
std::cout << size;
if(inputnum[i] == '.') {
break;
}
}
return 0;
}
(in my case with the following output:)
a
0a
1s
2d
3f
4g
5.
6Argento:Desktop marinos$
Your code seams OK as long as you're testing char against char in your loop and not something else.. Could it be that inputnum is some integral value ? if so, then your test clause will always evaluate to false unless inputnum matches the numerical value '.' is implicitly casted to..
EDIT
Apparently you are indeed trying to put char in a int[]. Try the following:
#include <iostream>
int main() {
using namespace std;
int size = 0;
int inputnum[50];
char inputchar[50];
for(int i=0;i<50;i++,size++) {
cin >> inputchar[i];
inputnum[i] = static_cast<int>(inputchar[i]); // or inputnum[i] = (int)inputchar[i];
cout << size << endl; // add a new line in the end
if(inputchar[i] == '.') break;
}
return 0;
}
Then again this is probably a lab assignment, in a real program I'd never code like this. Tat would depend on the requirements but I'd rather prefer using STL containers and algorithms or stringstreams. And if forced to work at a lower-level C-style, I'd try to figure out to what number '.' translates to (simply by int a = '.'; cout << a;`) and put that number directly in the test clause. Such code however might be simple but is also BAD in my opinion, it's unsafe, implementation specific and not really C++.

Assert function causes program to crash

I have used assert function to ensure that the first number input is between 1 and 7 (inclusive). However, when I execute the program and enter an invalid number, it causes the program to crash. So, how is the assert function being of any use here if that's the case?
Please correct my implementation where required.
Code:
#include <iostream>
#include <assert.h>
using namespace std;
int main() {
int num;
int n;
int max;
cout << "Please enter a number between 1 & 7 \n";
cin >> num;
assert(num >= 1 && num <= 7);
for (int i = 0; i < num; i++) {
cout << "Please enter number " << (i + 1) << ": ";
cin >> n;
if (i == 0) {
max = n;
}
max = (n > max) ? n : max;
}
cout << "The maxmum value is: " << max << endl;
system("pause");
return 0;
}
Assert is not what you want here. What you need is validation. Assertions are for debugging, for identifying completely invalid program states. The user entering invalid input is not invalid program state, it's just invalid user input.
To perform validation, you need an if-test. You will also need some code ready to handle the case of invalid user input. There's absolutely no way to prevent the user from providing invalid input (short of insanely aggressive dynamic validation where you capture keyboard events as they occur and prevent those keystrokes from translating into character input to your program, but now we're just getting ridiculous), so you need to react to it when it happens, say, by printing an error message and then asking for more input.
One way of doing this is as follows:
do {
cin >> num;
if (!(num >= 1 && num <= 7)) {
cerr << "invalid number; must be between 1 and 7!" << endl;
num = -1;
}
} while (num == -1);
Just to expand on that point about assertions, they are supposed to make the program crash. An assertion failure means your code is broken and must be fixed before it can be used in real life. Assertion failures should never be triggered in production code; they simply aid in testing and catching bugs.
What does the "crash" does? According to me, assert will abort the program execution, maybe as another value other than 0.

Program Compiles, Runs, but doesn't end in DevC++

I wrote a program to sum all odd numbers less than or equal to N. It's not the most efficient or eloquent program, but it works in the compiler on Codepad.org and does not work in DevC++. Usually when a program I wrote is stuck in some kind of infinite loop the program crashes in DevC++ and Windows stops it and lets me know.
Here, the program compiles and runs, but just sits with the cursor blinking and does nothing. Windows doesn't stop it, nothing happens, the program doesn't finish, no matter for how long I let it sit. I'm guessing this is a problem with DevC++ unless it's a problem with my code that Codepad overlooks. Will anyone explain to me what is happening here?
Here is my code:
#include <iostream>
using namespace std;
int odd(int N)
{
int i;
int sum = 0;
for(i = 0; i <= N; ++i)
{
while((i % 2) != 0)
{
sum = sum + i;
}
}
return sum;
}
int main()
{
int N;
cout << "Pick a value: ";
cin >> N;
cout << "The sum of all numbers <= to " << N << " is: " << odd(N);
return 0;
}
I've made the suggested change to an if-statement and the same problem is occuring:
#include <iostream>
using namespace std;
int odd(int N)
{
int i;
int sum = 0;
for(i = 0; i <= N; ++i)
{
if ((i % 2) != 0)
{
sum = sum + i;
}
}
return sum;
}
int main()
{
int N;
cout << "Pick a value: ";
cin >> N;
cout << "The sum of all odd numbers <= to " << N << " is: " << odd(N);
return 0;
}
while((i % 2) != 0)
{
sum = sum + i;
}
This is a infinite loop.Because if (i % 2 != 0) is true then the program will increment sum again and again.What you are probably looking to do is have an if statement instead of while
Seems like the edit is working, please try deleting the old output file and rebuilding and re-compile the entire program.
The output seems to be as follows:
Pick a value: 52
The sum of all odd numbers <= to 52 is: 676
Process exited after 1.034 seconds with return value 0
Press any key to continue . . .
make sure the window of the previous run is closed else the compiler will not recompile but just runs the previous version before you changed it.you may see this as an error stated at bottom in debug mode.
the while() is an infinite loop because i is not changed inside the while() or its {} so use if