C++ random 0xC0000005 errors - c++

I made a program which converts n decimal numbers sk into other numerical system p but sometimes it crashes and the error code I get is 0xC0000005 (program still converts and outputs all the numbers) . One thing I just noticed that it happens then converted number is longer than 6 symbols (or it's just a coincidence).
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
long n,sk,p,j;
string liekanos;
ifstream f("u1.txt");
f >> n;
for (int i=0;i<n;i++)
{
f >> sk >> p;
j=0;
while (sk>0)
{
liekanos[j]=sk % p;
sk/=p;
j++;
}
for (j>=0;j--;)
{
if (liekanos[j]<10)
cout<<int(liekanos[j]);
else cout<<char(liekanos[j]+55);
}
cout<<endl;
}
return 0;
}
Example input:
3
976421618 7
15835 24
2147483647 2

With liekanos[j] you access element at index j but since you haven't specify size of this string, you are most likely trying to access non-existing element. You could call liekanos.resize(sk) before you enter your while loop to make sure it never happens.
Or if you know the maximum possible size of liekanos, you could declare it as string liekanos(N, c); where N is its size and c is the default value of each character in it.

You are getting undefined behavior because your liekanos string never has any size or capacity.

string liekanos;
By default string has zero size. But you try to
liekanos[j]=sk % p;

Better use std::vector<char> liekanos; instead of string liekanos;.
You'll need to do some modifications in your code:
for (int i=0; i<n; i++)
{
std::vector<char> liekanos;
f >> sk >> p;
while (sk>0)
{
liekanos.push_back(sk % p);
sk/=p;
}
for (long j = liekanos.size(); j>=0; --j)
{
if (liekanos[j]<10)
cout<<int(liekanos[j]);
else cout<<char(liekanos[j]+'a');
}
cout<<endl;
}

Related

The question is about printing digits of two digit number n, I'm encountering a runtime error

Given a two-digit number n, print both the digits of the number.
Input Format:
The first line indicating the number of test cases T.
Next T lines will each contain a single number ni.
Output Format:
T lines each containing two digits of the number ni separated by space.
Constraints
1 <= T <= 100000
10 <= ni <= 99
Error: Runtime Error (SIGSEGV)
I'm not able to pinpoint, where the problem is in the code as it is working fine for a two numbers while it gives the runtime error for 4 or more numbers.
Is there another way of doing this problem other than using for loop twice?
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t;
int arr[t];
cin>>t;
for(int i=0;i<t;i++)
{
cin>>arr[i];
}
int c;
int b;
for(int i=0;i<t;i++)
{
c=(arr[i]/10);
if(c!=0)
{
b=arr[i]%(c*10);
}
else
{
b=arr[i];
}
cout<<c<<" "<<b<<endl;
}
return 0;
}
Fist, you declare t, but do not initialize it, so it is uninitialized. Trying to use the value leads to undefined behavior.
Second, VLA is not valid C++, see here. You have to use std::vector instead.
Third, you don't need to use an int.
So, you should do:
#include <iostream>
#include <vector>
#include <string>
int main()
{
int t{};
std::cin >> t;
std::vector<std::string> arr(t);
for(int i = 0; i < t; i++)
{
std::cin >> arr[i];
}
for(const auto &i : arr)
{
std::cout << i[0] << ' ' << i[1] << '\n';
}
}

frequency of a digit in an integer in c++

I have been given some integers and I have to count the frequency of a specific digit in the number.
example input:
5
447474
228
6664
40
81
The first number says number of integers in the list. I am finding frequency of 4 in this case. I tried to change the integer to an array, but it is not working.
#include<iostream>
#include<cmath>
#include<vector>
using namespace std;
int main() {
int n;
cin>>n;
for (int i=0; i<n; i++)
{
int x;
cin>>x;
int frequency=0;
int t=log10(x);
int arr[t];
for (i=t; i>0; i--)
{
arr[i]=x%10;
x=x/10;
}
for(int i=0; i<t; i++)
{
if(arr[i]==4)
{
frequency++;
}
}
std::cout << frequency << std::endl;
}
return 0;
}
No need to create an array, or to determine the number of digits. Just loop until the number reaches zero.
int digitCount(int n, int d) {
if(n < 0) n = -n;
int count = 0;
for(; n != 0; n /= 10)
if(n % 10 == d) count++;
return count;
}
Test:
cout << digitCount(447474, 4) << endl;
cout << digitCount(-447474, 4) << endl;
Output:
4
4
Your code uses VLAs which are not standard C++. See Why aren't variable-length arrays part of the C++ standard?.
log10(x) is not the number of digits. For example log10(1234) == 3.09131516 but it is 4 digits. Also you are accessing the array out of bounds in the first iteration of the loop: arr[t]. Valid indices in an array of size t are 0,1,2,...,t-1. Trying to access arr[t] is undefined behavior.
Actually you dont need any array. Instead of storing the digits in an array you can immediately check whether it is a 4 and count.
Even simpler would be to read the user input as a std::string:
#include <string>
#include <algorithm>
#include <iostream>
int main() {
std::string input;
std::cin >> input;
std::cout << std::count(input.begin(),input.end(),'4');
}
Perhaps you should add some checks to verify that the user input is actually a valid number. However, also when reading an int you should validate the input.

Program not calculating No. of combinations on each set from an n-digit number

The problem is to take 3 inputs:
1) No. of test cases
2) No. of digits in a number
3) N space separated digit numbers
And to output :
1) No. of sets
2) No. of combinations in each set
I want to print those outputs but No of combination output is returning zero on each and every set
I've already tried troubleshooting and debugging the problem, but none of those worked....
/* Read input from STDIN. Print your output to STDOUT*/
#include<iostream>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
using namespace std;
int factorial (int count);
int main(int argc, char *a[])
{
//intialize variables
int i,T,b,S[i],N,NN[i],C[i],count=0;
cin >> T;
while(T>0) {
cin >> N;
for(i=0;i<N;i++) {
cin >> NN[i];
if(i<N-1) {
S[i] = (N-i);// S[i] is Category 02
count++;
}//end of if
}//end of for loop
for(int j=0;j<N;j++) {
C[i] = factorial(count)/(factorial(i)*factorial(count - i));//
}//end of for loop
cout <<"No. of sets =" <<count++<<endl;
for(int k=0;k<N;k++) {
cout<<"No.of combinations on each set :";
cout<<C[i]<<endl;
} // end fo for loop
}//end of while loop
return 0;
}//end of main
int factorial(int count)
{
int i;
for(i = count-1; i > 1; i--)
count *= i;
return count ;
}//end of function
THIS OUTPUT IS COMING:
"No. of combinations on set 0 : 0"
"No. of combinations on set 1 : 0"
………….
Well it's gone wrong already here
//intialize variables
int i,T,b,S[i],N,NN[i],C[i],count=0;
What's the value of i here? Answer, it doesn't have one. If i doesn't have a value then what's the size of this array NN[i]? Answer, who knows.
When you declare an array in C++, you must give it a size. The size cannot be a variable, it must be a cosntant. And it especialy cannot be a variable without a value.
Your program has undefined behaviour.
EDIT - this would be an improvement
#include <vector>
int main()
{
int T;
cin >> T;
while (T > 0)
{
int N;
cin >> N;
std::vector<int> NN(N), S(N);
for (int i = 0; i < N; i++)
{
...
First improvement is that I using a std::vector instead of an array. Unlike arrays vectors can have variable sizes. Second improvement is that I only declare variables when I need them, I don't declare all the variables at the start of the function. So I only declare NN and S when I know what the value of N is, so I know how big the vectors need to be.

Error with a vector when I did permutation

I am trying to permutate my numbers in the vector.
Below are my codes. This code is very simple. Firstly, the input size of a vector is determined by user-input. And then, all the numbers in the vector are permutated in order to find the maximum integer value and minimum integer value when I concatenated all the numbers into one string.
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
string retS(const vector<int>& v)
{
string s = "";
for (int e : v) {
s += to_string(e);
}
return s;
}
int main(void) {
int num = 0;
cin >> num;
vector<int> numbers;
for (int i = 0; i < num; ++i) {
int n;
cin >> n;
numbers.push_back(n);
}
sort(numbers.begin(), numbers.end());
unsigned long long maxVal = 0;
unsigned long long minVal = 987654321;
do {
string s = retS(numbers);
if (stoll(s) > maxVal) {
maxVal = stoi(s);
}
if (stoll(s) < minVal)
minVal = stoi(s);
} while (std::next_permutation(numbers.begin(), numbers.end()));
cout << maxVal+minVal << endl;
}
However, the problem is that the error occurred when I inputted two digit numbers. For example, I inputted 10 20 30 40 50 60 70 80 90 20 into my vectors, then my codes didn't work. I think it is because the range of integer variable because the concatenated string can be a size of 20(~up to 20) if I assume only one or two digit number can be accepted.
Therefore, I changed my integer variable into unsigned long long type from int, which is, i think, the longest range value for storing integer type, but, the program was aborted when I executed.
So, Can you help me to have this code work well?
As Zereges noted the problem here is that you are trying to store a number that exceeds the capacity of the biggest numeric variable type that C++ has built-in. You can solve this problem storing such long numbers as strings. This will solve the problem you have, but it will make your code a bit slower.
If you don't want to fight with strings more than necessary this could help you: https://mattmccutchen.net/bigint/ It's a library to work with big integers.
Hope this helps
Sorry, I have made a mistake in my post.
---The Begining of the Mistake---
Firstly, below statement perhaps may not function as you expect.
sort(numbers.begin(), numbers.end());
According to this, sort() sorts the elements in the range [first,last) into ascending order. In fact, there is the same problem for std::next_permutation().
There indeed is a difference between parentheses and square brackets. [ means >= while ) means <. According to your code, the last element would not be sorted.
---The End of the Mistake---
I have just discovered that end() does not return an iterator referring to the last element in the vector container, but the past-the-end element, which is the theoretical element that would follow the last element in the vector.
Moreover, I see you have declared two unsigned long long to hold the values.
unsigned long long maxVal = 0;
unsigned long long minVal = 987654321;
It seems that 987654321 is the upper limit of the value you would like to store. However, there are few potential problems in your code which may make the value's upper bound fails.
(1) The upper limit is not applied to maxVal.
if (stoll(s) > maxVal) { //may add a upper boundary for maxVal
maxVal = stoi(s);
}
(2) The functions of stoll() and stoi() returns a long long and an int respectively. In case, a number greater than the upper limit of long long and int is caught, the above 2 functions will throw std::out_of_range exception. This is a restriction in using the functions. It seems this was the run-time error you have encountered. In addition, though you have tried to declare unsigned long long to store the values, it does not release the restriction in using the 2 functions.
To fix it, you may try the suggestion from Carlos.
Below is a possible implementation of the suggestion from Carlos.
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
string retS(const vector<int>& v)
{
string s = "";
for (int i = 0; i < v.size(); i++) {
s += to_string(v.at(i));
}
return s;
}
//prone to error
bool str1GreaterThanStr2(const string str1, const string str2)
{
if (str1.size() != str2.size())
return (str1.size() > str2.size());
int cursor = 0;
while (cursor < str1.size())
{
if (str1.at(cursor) != str2.at(cursor))
return (str1.at(cursor) > str2.at(cursor));
cursor++;
}
return false; //if both string are the same
}
int main(void) {
int num;
vector<int> numbers;
cin >> num;
for (int i = 0; i < num; ++i) {
int n;
cin >> n;
numbers.push_back(n);
}
sort(numbers.begin(), numbers.end());
string maxStr = retS(numbers);
string minStr = retS(numbers);
while (std::next_permutation(numbers.begin(), numbers.end()))
{
string str = retS(numbers);
maxStr = str1GreaterThanStr2(str, maxStr) ? str : maxStr;
minStr = str1GreaterThanStr2(str, minStr) ? minStr : str;
}
cout << maxStr << endl;
cout << minStr << endl;
}
/*
test case tried:
10
10 20 30 40 50 60 70 80 90 20
*/
Hope this helps.

c/c++ scanf/cin reads int from multiple lines

I'm doing some basic input parsing in c/c++.
format: number of values, followed by space separated values:
3
5 2 4
The problem here is the lack of a space after the first line. This causes cin and scanf to read 35 into the first variable, instead of 3.
int num;
scanf("%d", &num);
int array[num];
for (int i = 1; i <= num; i++) {
scanf("%d", &array[i]);
}
How do I get cin, or scanf, to stop parsing at a newline?
Edit:
Is it bad not to init variables even if they are written to later, before being read? (int num)
It works if I type the input in, but not if I paste it. Any clue?
std::cin interprets newline characters as spaces so there is the possibility the file you are working with contains something other than a newline. You are also using a non-standard extension to declare the array. This is not portable and not guaranteed to be supported by all compilers. I suggest you switch to using std::vector instead.
Your for loop is also incorrect. Array's used zero based indexing to access their elements. Because of this you end up accessing the array out of bounds which is undefined behavior. This means your program might crash, it may overwrite other variables or you might not notice any symptoms at all. This may also cause the symptom you are experiencing if it overwrites other variables.
The example below uses C++ input streams instead of scanf to provide better error checking.
#include <istream>
#include <vector>
std::vector<int> load(std::istream& in)
{
std::size_t count;
std::vector<int> data;
// If the user does not enter a number "in >> count" will fail.
if (in >> count)
{
int value;
while (count-- && in >> value)
data.push_back(value);
}
return data;
}
#include <iostream>
int main()
{
auto data = load(std::cin);
for (auto i : data)
std::cout << i << std::endl;
}
You can test this without reading from a file by using std::stringstream as the input.
#include <iostream>
#include <sstream>
int main()
{
std::stringstream text("3\n5 2 4");
auto data = load(text);
for (auto i : data)
std::cout << i << std::endl;
}
Within the for loop you started the array at position 1 and not 0. Which would cause going out of bounds, as you wanted to write to element 2 of the array. If you allocate an array of 2 elements the valid elements are going to be 0 and 1. This code works:
int num;
scanf("%d", &num);
int array[num];
for (int i = 0; i < num; i++)
{
scanf( "%d", &array[i] );
}
Start array from 0 as array indexes start from 0 - like:
for (int i = 0; i < num; i++)
You are starting first element from 1 that makes it undefined. Moreover, you should make dynamic array.
I liked Lidong Guo's code, and have modified it to run with Microsoft's C Compiler.
The only change was to move all of the data definitions ahead of any executable code, plus I added a space between the printed numbers.
#include <stdio.h>
#include <stdlib.h>
main()
{
int num;
int *array; //[num];
int i;
scanf("%d\n", &num);//here deal with the newlinw
array= malloc(sizeof(int) *num);//[num];
for (i = 0; i < num; i++)
{//the loop .start 0 end num -1
scanf("%d", &array[i]);
}
for (i = 0; i < num; i++)
{
printf("%d ", array[i]);
}
free(array);
}
[Edit: The Answere is specific to C++, as the Question also have a C++ tag]
Well first thing first.
You array defination is wrong .
int array[num]; // Super wrong way
You are not supposed to pass a variable as index while defining an array, its not allowed. Else, it will cause "nasal demon".
int * array = new int[num] //correct way
The code might be working correctly now but the array definition given by you lies under the category of UB.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
scanf("%d", &num);
int *array= malloc(sizeof(int) *num); // num is known at runtime
int i;
for (i = 0; i < num; i++) { //starts at 0, ends at num - 1
scanf("%d", &array[i]);
}
for (i = 0;i< num; i++) {
printf("%d", array[i]);
}
free(array);
}
Change the
scanf
statement to
scanf("%d", &array[i]);
Also array indexing starts from 0 and ends at num-1
Start your loop from 0 and end it at num-1,i.e
for (int i = 0; i < num - 1; i++)
scanf("%d", &array[i]);
And the reason for pasted input does not work is that it doesn't contain newline between two lines