Debug Assertion Fail (vector subscript out of range) - c++

I found that my result.push_back(make_pair(a[i], b[j]));, which
causing this error but i dont know why (i don't even access vector<pair<int,int>>result;)
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
#include<utility>
using namespace std;
void input(int n,vector<int>&a) {
int temps;
for (int i = 0; i < n; i++) {
cin >> temps;
a.push_back(temps);
}
}
int main() {
//input
long n, m;
cin >> n; //6
vector<int>a, b;
input(n, a); //{2 5 4 1 7 5}
cin >> m; //7
input(m, b); //{2 3 1 3 2 4 6}
//algorithm
long max = *max_element(a.begin(), a.end()) + *max_element(b.begin(), b.end());
long min = *min_element(a.begin(), a.end()) + *min_element(b.begin(), b.end());
vector<pair<int, int>>result;
int possible = max, plate = 0;
for (int check = max; check >= min; check--) {
int j = 0, i = 0, plate2 = 0;
for (; i < a.size(); i++) {
if (a[i] >= check) {}
else {
if (j > b.size() - 1) { break; }
if (a[i] + b[j] >= check) {
j++; plate2++;
result.push_back(make_pair(a[i], b[j]));
}
else {
i--; j++;
}
}
}
if (i > a.size() - 1) { possible = check; plate = plate2; break; }
}
cout << possible << " " << plate << endl; //5 3
return 0;
}
if you remove the line result.push_back(make_pair(a[i],b[j]);, there is no error message anymore, so i think i'm not access wrong a[i] and b[j] elements

if (j > b.size() - 1) { break; } //(1)
if (a[i] + b[j] >= check) { //(2)
j++; plate2++; // HERE IS YOUR PROBLEM (3)
result.push_back(make_pair(a[i], b[j])); //(4)
Assume that j == b.size()-1 at the beginning. The if (j > b.size() - 1) clause is false, so the loop does not break. It continues with (2), which is okay. In (3) you add +1 to j, so now j == b.size(). In (4) you try to access b[j], which is now b[b.size()], which is invalid, as indizes start at 0.
IOW: You tried to assure that j never points beyond the number of valid elements, but then you increment j after that test and access invalid memory.

Related

Why is this code giving me segmentation, ? when we print only count then it gives answer and when print ans[4] or any value then it gives error?

I am getting segmentation error , it gives output when only print ans[k] inside the function then it
gives corrct output but in main when I try to print ans[k] then it gives segmentation
i am new at progamming so i don't know more about it so please help me it's my assigment
question is
I have to create a array of factors of a number upto 4 * 10^6
Core Dump/Segmentation fault is a specific kind of error caused by accessing memory that “does not belong to you.”
When a piece of code tries to do read and write operation in a read only location in memory or freed block of memory, it is known as core dump.
It is an error indicating memory corruption.
#include <bits/stdc++.h>
using namespace std;
#define int long long int
vector<int> arr(1000001,0);
vector<int> ans;
bool isPrime(int n)
{
if (n <= 1)
return false;
if (n <= 3)
return true;
if (n % 2 == 0 || n % 3 == 0)
return false;
for (int i = 5; i * i <= n; i = i + 6)
if (n % i == 0 || n % (i + 2) == 0)
return false;
return true;
}
void factorpush()
{
for (int k = 5; k <= 4000001; k += 4)
{
if (isPrime(k))
{
arr[k] = 1;
}
}
arr.clear();
ans.clear();
for (int k = 5; k <= 4000001; k += 4)
{
if (arr[k] == 1)
{
int n = (k / 4);
ans[n] = (2 * n) - 1 + k;
}
else
{
vector<int> v;
for (int i = 1; i*i < k; i++)
{
if (k % i == 0)
{
if (k / i == i && i != k)
v.push_back(i);
else
{
if (i != k)
{
v.push_back(i);
}
if (k / i != k)
{
v.push_back(k/ i);
}
}
}
}
int count = k;
int count2 = 0;
for (auto x : v)
{
if (x != 1 && x!=k)
{
int n = (k/4);
count2 += ((2*n - 1)/x);
count += ((2*n - 1)/x)*x;
}
}
int n1 = (k/4);
int val = (2*n1) - 1 - count2;
count += val;
ans[n1] = count;
//cout<<ans[n1]<<"\n";
}
}
}
int32_t main()
{
factorpush();
int n;
cin>>n;
cout<<ans[n]<<"\n";`
return 0;
}
I didn't read your code well and there may be other errors, but at least the combination of
vector<int> arr(1000001,0);
and
for (int k = 5; k <= 4000001; k += 4)
{
if (isPrime(k))
{
arr[k] = 1;
}
}
is bad because arr[k] will go further than allocated.
You have to allocate enough elements like
vector<int> arr(4000002,0);
Also accessing arr[k] and ans[n] after arr.clear(); and ans.clear(); and without adding any elements is bad because the clear() function erases all elements from the vector. Also checking for arr[k] == 1 after the erasure doesn't make sense. Not understanding your code well, it looks like
arr.clear();
ans.clear();
should be replaced with something like
ans.clear();
ans.resize(1000001);

Wrong answer in Abbreviations problem using DP

Can someone explain what is wrong with my code? I am getting "Abort called" in 7 test cases. Rest are successful.
I have a 2d dp array with of size: n+1 x m+1 were n and m are sizes of a and b respectively. So, the row represent string a and columns represent string b.
First, I set dp[0][0] to 1 since it is possible to turn empty string into empty.
So, initially, i am checking if I can turn any substring of a into the empty string (in the first single for-loop). This is true for all substrings of a without any capital letters. As soon as there is a capital letter, the rest of the substrings cannot be converted.
Then (in the next double for-loop), I am examining all the cases.
Case 1: a[i-1] == b[i-1] -> if both the letter are the exact same, then dp[i][j] = dp[i-1][j-1]
Case 2: a[i-1] is lower case (this has 2 sub cases):
Case 2.1: a[i-1] and b[j-1] are the same letter (but not the same case) -> then we can either change a[i-1] or delete it . So:
dp[i][j] = dp[i-1][j-1] || dp[i-1][j].
Case 2.2: a[i-1] and b[j-1] are not the same -> in this case, we can only delete a[i-1] since it is lower case . So: dp[i][j] =
dp[i-1][j]
Link to problem: https://www.hackerrank.com/challenges/abbr/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=dynamic-programming
P.S. The main logic of the program is just inside the abbreviation() function.
Code (EDITTED):
#include <bits/stdc++.h>
using namespace std;
bool isSame(const char &a, const char &b)
{
return a == b || abs(a - b) == 32;
}
bool isLower(const char &a)
{
return a > 90 && a < 123;
}
// Complete the abbreviation function below.
string abbreviation(const string &a, const string &b)
{
int n = a.size(), m = b.size();
if (m > n)
return "NO";
vector<vector<bool>> dp(n + 1, vector<bool>(m + 1, 0));
dp[0][0] = 1;
for (int i = 1; i <= n; ++i)
{
if (isLower(a[i - 1]) && dp[i - 1][0])
dp[i][0] = 1;
}
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= i; ++j)
{
if (a[i - 1] == b[j - 1])
dp[i][j] = dp[i - 1][j - 1];
if (isLower(a[i - 1]))
{
if (isSame(a[i - 1], b[j - 1]))
dp[i][j] = dp[i - 1][j - 1] || dp[i - 1][j];
else if (dp[i - 1][j])
{
dp[i][j] = dp[i - 1][j];
}
}
}
}
return dp[n][m] ? "YES" : "NO";
}
int main()
{
int t;
cin >> t;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
while (t--)
{
string a, b;
getline(cin, a);
getline(cin, b);
cout << abbreviation(a, b) << "\n";
}
return 0;
}
The error in the code is "Segmentation fault".
Because of the following loop:
for (int j = 1; j <= i; ++j)
As the loop is iterating till i(which could be greater than m i.e. the size of b). That's the reason for the Segmentation fault.
Now the following code passes all the test cases.
#include <bits/stdc++.h>
using namespace std;
bool isSame(const char&a, const char&b){
return a==b || abs(a-b)==32;
}
bool isLower(const char&a){
return a >90 && a<123;
}
// Complete the abbreviation function below.
string abbreviation(string a, string b) {
int n = a.size(), m = b.size();
if(m>n)
return "NO";
int dp[n+1][m+1] = {};
dp[0][0] = 1;
for(int i=1; i<=n; ++i)
if(isLower(a[i-1]) && dp[i-1][0])
dp[i][0] = 1;
for(int i=1; i<=n; ++i)
for(int j =1; j<=min(i,m); ++j){
if(a[i-1]==b[j-1])
dp[i][j] = dp[i-1][j-1];
if(isLower(a[i-1]))
{
if(isSame(a[i-1], b[j-1]))
dp[i][j] = dp[i-1][j-1] || dp[i-1][j];
else if(dp[i-1][j])
dp[i][j] = dp[i-1][j];
}
}
return dp[n][m] ? "YES" : "NO";
}
int main()
{
int q;
cin >> q;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
for (int q_itr = 0; q_itr < q; q_itr++) {
string a;
getline(cin, a);
string b;
getline(cin, b);
string result = abbreviation(a, b);
cout << result << "\n";
}
return 0;
}

Why does the code below causes Segmentation Fault (SIGSEGV)?

PROBLEM STATEMENT
You are given a strictly increasing sequence of integers A1,A2,…,AN. Your task is to compress this sequence.
The compressed form of this sequence is a sequence of ranges separated by commas (characters ','). A range is either an integer or a pair of integers separated by three dots (the string "..."). When each range a...b in the compressed form is decompressed into the subsequence (a,a+1,…,b), we should obtain the (comma-separated) sequence A again.
For each maximal contiguous subsequence (a,a+1,…,b) of A such that b≥a+2, the compressed form of A must contain the range a...b; if b≤a+1, such a sequence should not be compressed into a range. A contiguous subsequence is maximal if it cannot be extended by at least one element of A next to it. It can be proved that the compressed form of any sequence is unique (i.e. well-defined).
Input
The first line of the input contains a single integer T denoting the number of test cases. The description of T test cases follows.
The first line of each test case contains a single integer N.
The second line contains N space-separated integers A1,A2,…,AN.
Output
For each test case, print a single line containing one string ― the compressed form of the given sequence.
Constraints
1≤T≤100
1≤N≤100
1 ≤ Ai ≤ 1000 for each valid i
A1 < A2 < …... <AN
Subtasks
Subtask #1 (100 points): Original constraints
Example Input
3
12
1 2 3 5 6 8 9 10 11 12 15 17
4
4 5 7 8
1
4
Example Output
1...3,5,6,8...12,15,17
4,5,7,8
4
MY Code:
#include <bits/stdc++.h>
using namespace std;
bool b[1005];
int a[1005];
int main()
{
int test, i, j, size, count;
cin >> test;
while (test--)
{
for (i = 0; i < 1005; i++)
b[i] = false;
cin >> size;
for (i = 0; i < size; i++)
{
cin >> a[i];
b[a[i]] = true;
}
for (i = 0; i < 1005; i++)
{
if (b[i] == true)
{
cout << i;
j = i;
count = 0;
while (b[j] == true)
{
count++;
j++;
}
if (count > 2)
{
i = j;
if ((j - 1) != a[size - 1])
cout << "..." << i - 1 << ",";
else
cout << "..." << i - 1;
}
if (count == 2)
{
i = j;
if ((j - 1) != a[size - 1])
cout << "," << i - 1 << ",";
else
cout << "," << i - 1;
}
if (count == 1 && ((j - 1) != a[size - 1]))
cout << ",";
}
}
}
return 0;
}
}
MY Question:
Above code runs perfectly on my device giving desired output. But when I am submitting this solution to
Online Judge , it says segmentation fault. It's sure that fundamentally I am accessing the memory incorrectly. Could you please show me where it is?
b is defined a bool[1005]
In this part
for(i=0 ; i<4000 ; i++)
b[i] = false;
You are writing false value 4000 times, exceeding the array size.
Overwriting past the array is allowed on the compiler but will have undefined behaviour in runtime.
In short: it can or can not cause a segfault.
Here is another approach given that the input data is in a file input.txt:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
class Reader {
public:
Reader(const std::string& filename) :
filename_(std::move(filename)), is_(filename_)
{
is_.exceptions( std::ifstream::failbit | std::ifstream::badbit );
}
int get_N() {
int N;
is_ >> N;
return N;
}
std::vector<int> get_ints(int N) {
std::vector<int> v;
v.reserve(N);
for (int i = 0; i < N; i++ ) {
int value;
is_ >> value;
v.push_back(value);
}
return v;
}
int get_num_cases() {
int num_cases;
is_ >> num_cases;
return num_cases;
}
private:
std::string filename_;
std::ifstream is_;
};
bool start_range_cur( std::vector<int> &v, int j, int N )
{
if ( j>= (N - 2) ) return false;
return ((v[j+1] - v[j]) == 1) && ((v[j+2] - v[j+1]) == 1);
}
bool in_range_cur( std::vector<int> &v, int j )
{
return (v[j+1] - v[j]) == 1;
}
void print_range( int min, int max, bool print_comma)
{
std::cout << min << ".." << max;
if (print_comma) std::cout << ",";
}
void print_single(int val, bool print_comma)
{
std::cout << val;
if (print_comma) {
std::cout << ",";
}
}
int main() {
Reader is {"input.txt"};
int num_cases = is.get_num_cases();
for (int i = 0; i < num_cases; i++) {
int N = is.get_N();
std::vector<int> v = is.get_ints(N);
bool in_range = false;
int range_start;
for( int j = 0; j< N; j++ ) {
if (in_range) {
if (j == (N - 1)) {
print_range(range_start, v[j], false);
}
else if (in_range_cur(v, j)) {
continue;
}
else {
print_range(range_start, v[j], true);
in_range = false;
}
}
else {
if (j == (N - 1)) {
print_single(v[j], false);
}
else if (start_range_cur(v, j, N)) {
in_range = true;
range_start = v[j];
}
else {
print_single(v[j], true);
}
}
}
std::cout << '\n';
}
return 0;
}

Check whether all the pairs in an array are divisible by k

Given an array of integers and a number k, write a function that returns true if given array can be divided into pairs such that sum of every pair is divisible by k.
This code is producing correct results for all test cases except one I cannot find the glitch in it.
#include <bits/stdc++.h>
using namespace std;
int main() {
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
int arr[n];
for (int i = 0; i < n; i++) {
cin >> arr[i];
}
int k;
cin >> k;
int flag[n] = {0};
int p = 0;
int q = 0;
if (n % 2 != 0) {
cout << "False" << endl;
} else {
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if ((arr[i] + arr[j]) % k == 0 && flag[j] == 0) {
p = 1;
flag[j] = 1;
}
}
if (p == 0) {
q = 1;
cout << "False" << endl;
break;
}
}
if (q == 0) {
cout << "True" << endl;
}
}
}
return 0;
}
One of the big sources of bugs in code is messy code. So how do we clean up code? We modularize it. This means breaking up the code so that each portion of the code does one job well. Let's see what that looks like.
Function to check if something is divisible by k:
bool isDivisible(int number, int divisor) {
return number % divisor == 0;
}
Function to check all pairs:
The logic is as follows:
Take the first number in the list; call in n0.
For every remaining number n1, check if that plus the first number is divisible by k
When we find n1 such that n0 + n1 is divisible by k,
a. If the remaining numbers left over can also be split into divisible pairs, return true
b. Otherwise, continue searching
4.If we've searched through all the numbers, return false.
bool pairsDivisible(int* nums, int count, int k) {
if(count == 0) return true;
if(count % 2 != 0) return false; // count must be even
// 1.
int n0 = nums[0];
// 2.
for(int i = 1; i < count; i++) {
int n1 = nums[i];
// 3.
if(isDivisible(n0 + n1, k)) {
// Move the ith number so it's now nums[1]
std::swap(nums[1], nums[i]);
if(pairsDivisible(nums + 2, count - 2, k)) {
return true; // 3.a
} else {
// Reset the array
std::swap(nums[1], nums[i]);
}
}
}
return false;
}

Memory error in finding prime sum

Problem: Given an even number ( greater than 2 ), return two prime numbers whose sum will be equal to given number.
Solution: Using sieve of eratosthenes find all prime numbers upto given number. Then find the pair of numbers whose sum is equal to given number.
Code:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
void primesum(int A)
{
std::vector<bool> primes(A + 1, 1);
std::vector<int> arr, final;
primes[0] = 0;
primes[1] = 0;
for (int i = 2; i <= int(sqrt(A)); i++)
{
if (primes[i] == 1)
{
for (int j = 2; i + j <= A; j++)
{
primes[i * j] = 0;
}
}
}
for (int i = 0; i < primes.size(); i++)
if (primes[i])
arr.push_back(i);
/* for (auto x : primes)
std::cout << x << " ";
std::cout << "\n"; */
std::vector<int>::iterator it;
for (int i = 0; i < arr.size(); i++)
{
it = std::find(arr.begin(), arr.end(), A - arr[i]);
if (it != arr.end())
{
final.push_back(arr[i]);
final.push_back(A - arr[i]);
break;
}
}
std::cout << final[0] << " " << final[1] << "\n";
return;
}
int main()
{
int x = 184;
primesum(x);
return 0;
}
This code is working for most of the cases except for case like when x=184. Error in this case is:
a.out: malloc.c:2394: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.
[1] 13944 abort (core dumped) ./a.out
I'm not able to understand why this is happening and what's its solution?
Let x=184. Then primes.size() is 185. The first loop iterates till i=13. 13 is the prime number. The second loop iterates till j=171. In the loop you access primes[2223]. It is a write out of bounds, causes UB. As the result you get corrupted dynamic memory and the assertion.
It looks like you did a typo in the loop condition, you wanted i * j <= A.
With primes[i * j] = 0 you have invalid indices exceeding your vector size while finding the primes, that is the reason this code crashes. You can correct this to
for (int i = 2; i <= int(sqrt(A)); i++)
{
if (primes[i] == 1)
{
for (int j = 2; i * j <= A; j++)
{
primes[i * j] = 0;
}
}
}