C++ segmentation fault using erase in a vector - c++

I am getting segmentation fault during my code and I was wondering why. I am taking a guess its something with the vector.erase() function.
#include <iostream>
#include <vector>
#include <math.h>
long long gcd(long long x, long long y);
std::vector<long long> factor(long long x);
typedef std::vector<long long> vectorNum;
int main(int argc, const char * argv[])
{
// insert code here...
long long unFriendly;
long long friendly;
long long counter = 0;
std::cin >> unFriendly;
std::cin >> friendly;
vectorNum n;
n = factor(friendly);
for(long long x = 0;x < unFriendly;x++){
long long num = 0;
std::cin >> num;
counter = gcd(friendly, num);
for(long long y = n.size() - 1;y >= 0;y--){
vectorNum temp(n);
if(counter % n.at(y) == 0){
n.erase(n.begin() + y);
}
}
}
std::cout<<n.size();
n.clear();
}
long long gcd(long long x, long long y){
while(y != 0){
long long a = x % y;
x = y;
y = a;
}
return x;
}
std::vector<long long> factor(long long x){
long long y;
long long root = sqrt(x);
std::vector<long long> vectorSet;
for(y = 2; y <= root;y++){
if(x % y == 0){
vectorSet.push_back(y);
vectorSet.push_back(x / y);
}
}
vectorSet.push_back(x);
return vectorSet;
}
Any kinds of insight would be perfect! Thanks in advance.
This is both the functions that are being called. Both of the gcd() and the factors() function as requested.

for(long long x = 0;x < unFriendly;x++){
long long num = 0;
std::cin >> num;
counter = gcd(friendly, num);
for(long long y = n.size() - 1;y >= 0;y--) { // <-- n.size() == 0, 0U - 1 is huge
vectorNum temp(n);
if(counter % n.at(y) == 0){ // <-- y is huge, throws std::out_of_range
n.erase(n.begin() + y);
}
}
}
I would strongly recommend running your code under a debugger. The Visual Studio debugger when running your code pretty quickly displayed this:

Your program will crash if friendly is 0. This is because the factor function will push 0 to the return vector. Inside your inner most loop, accessing n.at(y) will give the value 0 and dividing counter by 0 generates an exception that segfaults your application.

Related

std::bad_array_new_length for large numbers

I try to run following code:
#include <stdio.h>
#include <stdlib.h>
int find_next(int act, unsigned long long survivors[], int n)
{
int i = act;
while (survivors[i] == 0)
{
i++;
i = i % n;
}
i = (i + 1) % n; // found first one, but need to skip
while (survivors[i] == 0)
{
i++;
i = i % n;
}// thats the guy
return i;
}
int main()
{
long long int lines;
long long int* results;
scanf_s("%llu", &lines);
results = new long long int[lines];
for (long long int i = 0; i < lines; i++) {
unsigned long long n, k;
scanf_s("%llu", &n);
scanf_s("%llu", &k);
unsigned long long* survivors;
survivors = new unsigned long long[n];
for (int m = 0; m < n; m++) {
survivors[m] = 1;
}
int* order;
order = new int[n];
int p = 0;
int act = 0;
while (p < n - 1)
{
act = find_next(act, survivors, n);
order[p] = act;
survivors[act] = 0; // dies;
p++;
}
order[p] = find_next(act, survivors, n);
if (k > 0)
{
results[i] = order[k - 1] + 1;
}
else
{
results[i] = order[n + k] + 1;
}
delete[] survivors;
delete[] order;
}
for (long long int i = 0; i < lines; i++) {
printf("%llu\n", results[i]);
}
delete[] results;
return 0;
}
My inputs are:
1
1111111111
-1
I am getting an exeption:
std::bad_array_new_length for large numbers
At line:
survivors = new unsigned long long[n];
How should I fix it that it wont show for such large numbers?
So far I tried all numeric types of n -> long long int, unsigned long and so on but everytime I was failing. Or maybe there is no way around that?
How should I fix it that it wont show for such large numbers?
Run the program on a 64 bit CPU.
Use a 64 bit operating system.
Compile the program in 64 bit mode.
Install sufficient amount of memory. That array alone uses over 8 gigabytes.
Configure operating system to allow that much memory be allocated for the process.
P.S. Avoid owning bare pointers. In this case, I recommend using a RAII container such as std::vector.

Fibonacci Number modulo m

Task: Given two integers n and m, output Fn mod m (they is, the remainder of Fn when divided by m).
My Code:
#include <iostream>
#include <vector>
using namespace std;
long long get_pisano_period(long long m)
{
long long a = 0, b = 1, c;
for (int i = 0; i < m * m; i++)
{
c = (a + b) % m;
a = b;
b = c;
if (a == 0 && b == 1)
return i + 1;
}
}
long long calc_fib(long long n)
{
vector<long long> nums(n + 1);
nums.at(0) = 0;
nums.at(1) = 1;
for (long long i = 2; i < nums.size(); i++)
{
nums.at(i) = nums.at(i - 1) + nums.at(i - 2);
}
return nums.at(n);
}
long long solve(long long n, long long m)
{
long long r = n % get_pisano_period(m);
return (calc_fib(r) % m);
}
int main()
{
long long n, m;
cin >> n >> m;
cout << solve(n, m) << endl;
return 0;
}
My code is working for some cases(small numbers). Can anyone suggest to me, What changes should I make to run this?
Input:
239
1000
Output:
-191
You can see I am supposed to get 161 as output.
I tried what #idclev463035818 said and this seems to work.
Try it,
# include <iostream>
# include <vector>
using namespace std;
long long get_pisano_period(long long m)
{
long long a = 0, b = 1, c;
for (long long i = 0; i < m * m; i++)
{
c = (a + b) % m;
a = b;
b = c;
if (a == 0 && b == 1)
return i + 1;
}
}
long long calc_fib(long long n, long long m)
{
vector<long long> nums(n + 1);
nums.at(0) = 0;
nums.at(1) = 1;
long long maximum = get_pisano_period(m);
for (long long i = 2; i < nums.size(); i++)
{
nums.at(i) = (nums.at(i - 1)%m + nums.at(i - 2)%m)%m;
}
return nums.at(n);
}
int main()
{
long long n, m;
cin >> n >> m;
cout << calc_fib(n, m) << endl;
return 0;
}

Why does loop runs 1 or 2 times only when I use rand() function in c++

I want to generate random test cases for my program, but it crashes after running 1 or 2 times.
I have used rand() function to generate random numbers for random test cases
but it is not running after one or sometimes two times.. and does not generate any random number. The program simply exits.
#include<bits/stdc++.h>
#include<ctime>
#include <time.h>
using namespace std;
long long int naive(long long int arr[],long long int n){
long long int max=-1;
for(long long int i=0;i<n;i++)
{
for(long long int j=0;j<n;j++){
if(arr[i]%arr[j] > max){
max = arr[i]%arr[j];
}
}
}
return max;
}
long long int efficent(long long int arr[],long long int n){
long long int max1=0,max2=0;
for(long long int i=0;i<n;i++){
if (arr[i] > max1)
{
max2 = max1;
max1 = arr[i];
}
else if (arr[i] > max2 && arr[i] != max1)
max2 = arr[i];
}
return max2%max1;
}
int main(){
srand(time(0));
long long int count=0;
int t=10;
while(t--){
long long int n;
n = rand()%10;
long long int arr[n];
for(long long int i=0;i<n;i++){
arr[i] = rand()%10;
}
long long int a,b;
a = naive(arr,n);
b = efficent(arr,n);
if(a == b)
cout<<"Naive : "<<a<<"\tEfficent : "<<b<<"\n";
else{
cout<<"\nNot Equal."<<"\nCount : "<<++count<<endl;
cout<<"Naive : "<<a<<"\tEfficent : "<<b<<"\n";
}
}
return 0;
}
In addition to the memory leaks and not declaring a variable sized array correctly mentioned in the other answer, the issue is that you are performing the mod operation on values that could be 0. This will force your program to exit. To fix this, change
arr[i] = rand()%10;
to something like
arr[i] = rand()%10+1;
to prevent division by 0.
EDIT: as mentioned by #Michael Dorgan, you should probably do the same for n. Change
n = rand()%10;
to
n = rand()%10+1;
to prevent 0 length arrays from being allocated.
This code is problematic:
while(t--){
long long int n;
n = rand()%10;
long long int arr[n];
for(long long int i=0;i<n;i++){
arr[i] = rand()%10;
}
If you need a variable size array, you should use long long int * arr = new long long int[n]; and delete[] arr; before the last closing brace of the while block.

Princess Farida on Spoj

I stuck at a problem SPOJ.
I checked all the test cases passing all of them, but I am still getting "WA" on spoj.
I know it can be solved using dynamic programming, but I am practicing memoization.
Here is my code:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector <int> dp(1000000);
long long int maxloot(vector<int> &loot, int n) {
if (n == 0)
return 0;
if (n == 1)
return loot[0];
if (n == 2)
return max(loot[0], loot[1]);
if (dp[n] != -1)
return dp[n];
long long int take = loot[n - 1] + maxloot(loot, n - 2);
long long int leave = maxloot(loot, n - 1);
return dp[n]= max(take, leave);
}
int main() {
int t;
cin >> t;
int p = 1;
while (t--) {
int n;
cin >> n;
vector <int> loot;
for (int i = 0; i < n; i++) {
int temp;
cin >> temp;
loot.push_back(temp);
}
dp.assign(1000000, -1);
cout <<"Case "<<p<<": "<< maxloot(loot, n)<<endl;
p++;
dp.clear();
}
}
Test case 1:
5
1 2 3 4 5
Test case 2:
1
10
output 1:
9
output 2:
10
You are using wrong data type to store value in vector dp.
As the sum of coins can go up to (10^9*10^2=10^11) therefore int would not be able to store it .Try using long long int instead as it would not lead to overflow condition.
SAME CODE AS YOURS(using long long int got accepted):
USE: vector< long long int>dp(1000000)
ACCEPTED CODE:
#include<iostream>
#include<vector>
#include<algorithm>
#define ull unsigned long long
using namespace std;
vector <long long int> dp(1000000);
long long int maxloot(vector<int> &loot, int n) {
if (n == 0)
return 0;
if (n == 1)
return loot[0];
if (n == 2)
return max(loot[0], loot[1]);
if (dp[n] != -1)
return dp[n];
long long int take = loot[n - 1] + maxloot(loot, n - 2);
long long int leave = maxloot(loot, n - 1);
return dp[n]= max(take, leave);
}
int main() {
int t;
cin >> t;
int p = 1;
while (t--) {
int n;
cin >> n;
vector <int> loot;
for (int i = 0; i < n; i++) {
int temp;
cin >> temp;
loot.push_back(temp);
}
dp.assign(1000000, -1);
cout <<"Case "<<p<<": "<< maxloot(loot, n)<<endl;
p++;
dp.clear();
}
}

Saving unknown amount of integers without taking too much time/memory

#include <iostream>
using namespace std;
unsigned long long divsum(unsigned long long x);
int main()
{
unsigned long long x;
cin >> x;
unsigned long long y[200000];
for (unsigned int i = 0; i < x; i++)
cin >> y[i];
for (unsigned int i = 0; i < x; i++){
cout << divsum(y[i]) << endl;
}
return 0;
}
unsigned long long divsum(unsigned long long x){
int sum = 0;
for(unsigned int i = 1; i <= x/2; i++){
if(x % i == 0)
sum += i;
}
return sum;
}
I'm doing an online exercise and it says there are possible 2000000 cases in the first line, so I made an array of that amount, however, when I submit the solution it exceeds the time.. so I was wondering what is an alternative and faster way to do this? The program works fine right now, except it exceeds the time limit of the website.
You can allocate the array dynamically, so it will work better in cases where x < 200000
int main()
{
unsigned long long x;
cin >> x;
unsigned long long *y = new unsigned long long[x];
// you can check if new didn't throw an exception here
for (unsigned int i = 0; i < x; i++)
cin >> y[i];
for (unsigned int i = 0; i < x; i++){
cout << divsum(y[i]) << endl;
}
delete[] y;
return 0;
}
Since you know the size of the array, try vector and reserve.
int main()
{
unsigned long long x;
cin >> x;
unsigned long long var;
vector<unsigned long long> y;
y.reserve(x);
for (unsigned int i = 0; i < x; i++){
cin >> y[i];
}for (unsigned int i = 0; i < x; i++){
cout << divsum(var) << endl;
}
return 0;
}
And deal in const &
const unsigned long long & divsum(const unsigned long long & x){
int sum = 0;
unsigned long long x2 = x/2
for(unsigned int i = 1; i <= x2; i++){
if(x % i == 0)
sum += i;
}
return sum;
}
I think your assignment is more complex than you think. Your divsum(x) function should return sum of all divisors of x, right? In this case it's better to factorize the x, and calculate this sum using all the prime numbers (with powers), product of which is equal to the x. Take a look at:
http://en.wikipedia.org/wiki/Divisor_function
There are methods for recursive factorization - for example, if you have factorized all numbers until n, you can quickly find factorization for (n + 1). You also need to generate primes, Erathosphene sieve for first 2000000 numbers would be fine.