I am getting a SIGABRT error when I compile the following code.(PRIME1 problem of spoj).
Link of the problem is http://www.spoj.com/problems/PRIME1/. It runs well on codeblocks but spoj returns SIGABRT error. Can someone explain the reason?
int main()
{
long long k,x,j=0,size,l=0,p=0,q=0,r=0,s;
cin>>size;
int a[(2*size)];
cout<<endl;
for(int i=0; i< (2*size); i++)
{
cin>>a[i];
}
if( size == 1)
{
p=a[1];
}
else
{
do
{
if(a[l+3]>a[l+1])
{
p=a[l+3];
}
else
{
p=a[l+1];
}
l=l+2;
}while(l<2*(size-1));
}
cout<<p;
long * b = new long [p-1];
for(long long i=0;i<p-1;i++)
{
b[i]=1;
}
b[0]=b[1]=0;
s=sqrt(p)
for(long long i = 2; i <= s; i++)
{
if(b[i] == 1)
{
for(long long j = i*i; j <= p; j = j + i)
{
b[j] = 0;
}
}
}
while(r<(2*size))
{
for(long long i = a[r];i < a[r+1];i++)
{
if(b[i] == 1 )
{
cout << i << "\n";
}
}
cout<<endl;
r=r+2;
}
delete [] b;
}
You are accessing array element accessing outside bounds
Array size 2*size-1 So elements from 0 to 2*size-2
But in your for loop you are going upto 2*size thus accessing 2*size-1 which is outside bounds
int a[(2*size)-1];
This is not legal C++ code (it's using a GCC extension), but it obviously compiled, so we'll let that slide. You are accessing your array out of bounds in the following loop and all over the place later on, which is undefined behavior - you need an array of size 2 * size to read in all the supplied parameters. Although given that they guarantee that size <= 10, you might as well just declare it as int a[20];
But that probably didn't cause the crash. What caused the crash is probably this line:
long * b = new long [p-1];
What's p? Well, let's just consider the easy case of size = 1 where you set p to a[1], or the second number you read in. What's the bounds on that number?
The questions says that the bound is n <= 1000000000, or 109. Your new can be requesting as much as 8GB of memory, depending on the value of sizeof(long) in the system you are using. The allocation is almost certainly going to fail, throwing a std::bad_alloc exception that causes std::abort() to be called as you don't have any exception handling code.
You initialize a to 2 * size - 1 elements...
int a[(2*size)-1];
Yet you write 2 * size elements.
for(int i=0; i< (2*size); i++)
// ...
Your loop should be:
for(int i=0; i< (2*size-1); i++)
Next...
if(size == 1)
{
p=a[1];
}
If size == 1 then you allocated an array of 2 * 1 - 1 = 1 element, so a[1] is an invalid access (you only have a[0] as arrays are 0-indexed).
You then have stuff like this:
if(a[l+3]>a[l+1])
Which loops until l == 2*size-1, so l+3 is invalid as soon as you hit 2 * size - 1 - 3.
Basically you just have a lot of places where you're reading or writing past the end of an array or not ensuring proper initialization and invoking undefined behavior.
Related
I was creating a function that takes an integer number, finds the next multiple of 5 after the number and then if the difference between the multiple and the number is less than 3, then it prints out the multiple else the number itself, finally prints out an array of all the numbers.
#include <bits/stdc++.h>
#include <iostream>
using namespace std;
vector<int> gradingStudents(vector<int> grades) {
int size=grades.size();
int c=0;
int d;
vector<int> array;
for(int i=0;i<size;i++){
while(grades[i]>(c*5)){
c++;
}
d=c*5;
if((d-grades[i])<3){
array[i]=d;
}else{
array[i]=grades[i];
}
d=0;
c=0;
}
return array ;
Now I tried running this function, and the compiler gives shows no error in the program in the code, however the code doesn't print anything.
Someone Please help.
First, I have to say that this code is extremely inefficient. Finding the difference between the closest muliplication of 5 and a number can be simply done by:
int difference = (n - (n + 4) / 5 * 5) - n;
Explanation: C++ is rounding down the division, so (n + 4) / 5 is n / 5 rounded up, and hence (n+4)/5*5 is the closest multiplication of 5.
Another thing, you declare an array but never resize it, so its size is 0. You need to resize it either by specifying the size in the constructor or using the std::vector::resize method.
code:
std::vector<int> gradingStudents(std::vector<int> grades) {
std::size_t size = grades.size();
std::vector<int> array(size);
for (int i = 0; i < size; i++) {
int closestMul = (grades[i] + 4) / 5 * 5;
if (closestMul - grades[i] < 3) {
array[i] = closestMul;
}
else {
array[i] = grades[i];
}
}
return array;
}
Proably your code is crashing, which is why it doesn't print anything. And one reason it might be crashing is your vector use is wrong.
It's very common to see beginners write code like this
vector<int> array;
for (int i=0;i<size;i++) {
array[i] = ...;
But your vector has zero size. So array[i] is an error, always.
Two possible solutions
1) Make the vector the correct size to begin with
vector<int> array(size);
for (int i=0;i<size;i++) {
array[i] = ...;
2) Use push_back to add items to the vector, every time you call push_back the vector increases in size by one.
vector<int> array(size);
for (int i=0;i<size;i++) {
array.push_back(...);
And please don't call your vector array, that's just taking the piss.
i feel nothing is wrong with your function but calling of this function is a bit tricky let me give you a quick main to try may be that will help you.
int main() {
vector <int> test ;
test.push_back(1);
test.push_back(2);
gradingStudents(test);
return 0;
}
Try initially the size of the vector is empty i hope you are sending something from the main . Your code is very inefficient whenever you find time must read how to write an efficient code.
This project is a homework assignment for school. The instructor has asked us to input 20 random integers then print the smallest in the list and then search the list for the first iteration of the number entered. My problem is returning the smallest number of the list. The function, shown below accepts an integer array and an integer with the size of the array. In Visual Studio, the tests for the smallest number work until the function returns the value. Instead of returning the smallest number, the function returns some kind of default value as opposed to the smallest integer. I have been staring at this code for the past two hours, any help would be appreciated.
int theSmallest(const int a[], int number_used)
{
int temp = a[0];
// Find the smallest number in array a[]
for (int i = 0; i <= number_used; i++)
{
if (temp >= a[i])
{
temp = a[i];
}
}
return temp;
}
Your program has undefined behavior because you are accessing the array a using an invalid index.
When an array has 20 elements, the valid indices are 0-19, not 0-20.
You are using
for (int i = 0; i <= number_used; i++)
and then accessing a[i] in the loop. If number_used is equal to 20, you are accessing a using and index value of 20, which is not correct.
Change that to use i < number_used.
for (int i = 0; i < number_used; i++)
A minor issue is that you are using temp >= a[i], which can be changed to use temp > a[i]. Use of >= in this case will work but it will do more work than necessary.
Here's an updated version of the function:
int theSmallest(const int a[], int number_used)
{
int temp = a[0];
// Find the smallest number in array a[]
for (int i = 1; i < number_used; i++)
{
if (temp > a[i])
{
temp = a[i];
}
}
return temp;
}
Assuming number_used is the size of array, code can be written as:
int theSmallest(const int a[], int number_used)
{
if( a == nullptr or number_used == 0 )
throw std::runtime_error( "invalid argument" );
return *std::min_element( a, a + number_used );
}
Note: you code has issue in case number_used is equal to 0 or a pointer is passed as nullptr, you may not expect that to happen but it is good idea to always validate your input (at least by assert())
Change to i < number_used and I think change to if(temp > a[i]).
You can also start i=1 since you made the assumption index 0 is the smallest.
Change
for (int i = 0; i <= number_used; i++)
to
for (int i = 1; i < number_used; i++)
I'm in a linux server and when I try to execute the program it's returning a segmentation fault. when i use gdb to try and find out why, it returns..
Starting program: /home/cups/k
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401128 in search(int) ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.192.el6.x86_64 libgcc-4.4.7-17.el6.x86_64 libstdc++-4.4.7-17.el6.x86_64
I couldn't quite interpret this. In my program i have a function called "search()" but i don't see anything that would cause a seg fault. here's the function def:
int search (int bit_type) { // SEARCH FOR A CONSEC NUMBER (of type BIT_TYPE) TO SEE IF ALREADY ENCOUNTERED
for (int i = 1; i <= MAX[bit_type]; i++) { //GO THRU ALL ENCOUNTERED CONSEC NUMBERS SO FAR (for type BIT_TYPE)
if (consec == r[bit_type][i]) // IF: FOUND
return i; // -----> RETURN INDEX OF RECORDED CONSEC_NUM
}
// IF: NOT FOUND
r[bit_type][++MAX[bit_type]] = consec; // -----> INCREMENT MAX[bit_type] & RECORD NEW CONSEC_NUM -------> ARRAY[MAX]
n[bit_type][MAX[bit_type]] = 1;
return (MAX[bit_prev]); // -----> RETURN THE NEWLY FILLED INDEX
}
global functions:
int MAX[2];
int r[2][200];
int n[2][200];
The comments are pretty useless to you guys since you don't have the rest of the program.. but you can just ignore them.
But do you guys see anything I missed?
From the link to your code here, here is just one error:
int *tmp = new int[MAX[0]];
for (int y = 0; y <= MAX[0]; y++) {
tmp[y] = 1;
}
You are going out-of-bounds on the last iteration. You allocated an array with MAX[0] items, and on the last iteration you're accessing tmp[MAX[0]].
That loop should be:
int *tmp = new int[MAX[0]];
for (int y = 0; y < MAX[0]; y++) {
tmp[y] = 1;
}
or better yet:
#include <algorithm>
//...
std::fill(tmp, tmp + MAX[0], 1); // no loop needed
or skip the dynamic allocation using new[] and use std::vector:
#include <vector>
//...
std::vector<int> tmp(MAX[0], 1);
In general, you have multiple loops that do this:
for (int i = 1; i <= number_of_items_in_array; ++i )
and then you access your arrays with array[i]. It is the <= in that for loop condition that is suspicious since it will try to access the array with an out-of-bounds index on the last iteration.
Another example is this:
long sum(int arr_r[], int arr_n[], int limit)
{
long tot = 0;
for (int i = 1; i <= limit; i++)
{
tot += (arr_r[i])*(arr_n[i]);
}
return tot;
}
Here, limit is the number of elements in the array, and you access arr_r[i] on the last iteration, causing undefined behavior.
Arrays are indexed starting from 0 and up to n - 1, where n is the total number of elements. Trying to fake 1-based arrays as you're attempting to do almost always results in these types of errors somewhere inside of the code base.
I am getting the std::bad alloc() exception in a code I have written. According to other answers on SO, I should free the dynamically allocated memory but the exception remains. Any leads on how I can solve it?
I am attaching the function where the error comes.
int count(int *S, int m, int n ) {
int i, j, x, y;
// We need n+1 rows as the table is consturcted in bottom up manner using
// the base case 0 value case (n = 0)
int **table=new int*[n+1];
for(int q=0;q< n+1;q++)
table[q] = new int[m];
// Fill the enteries for 0 value case (n = 0)
for (i=0; i<m; i++)
table[0][i] = 1;
// Fill rest of the table enteries in bottom up manner
for (i = 1; i < n+1; i++)
{
for (j = 0; j < m; j++)
{
// Count of solutions including S[j]
x = (i-S[j] >= 0)? table[i - S[j]][j]: 0;
// Count of solutions excluding S[j]
y = (j >= 1)? table[i][j-1]: 0;
// total count
table[i][j] = x + y;
}
}
int answer = table[n][m-1];
delete[] table;
return answer; }
I am basically trying to solve the coin exchange problem. n can be as big as 10^9.
Notice when you allocate table you do it in two steps. You allocate table and then each element of table. To release all the memory you must also use two steps, each table element and finally table itself.
Change your cleanup to something like:
for(int q=0;q< n+1;q++) {
delete[] table[q];
}
delete[] table;
...or just use std::vector and avoid manual memory management.
I wrote this program using Sieve of Eratosthenes. It is supposed to output prime numbers up to 2'500'000, but it crashes when trying to create array bigger than ~2'100'000. Any ideas what might be broken?
Compiling with gcc in Code::Blocks (Windows 8.1, shame on me).
PS It works flawless for N <= 2'000'000
#include <stdio.h>
int main() {
// Input
long n;
scanf("%ld", &n);
// Initialize vars
bool number[n+1];
for(long i = 0; i < n; i++)
number[i] = false;
// Main loop
for(long i = 2; i*i <= n; i++) {
if(number[i]) // If number is already removed
continue; // Do next number
// Remove x * i
for(long j = i*2; j <= n; j += i)
number[j] = true;
}
// Print
for(long i = 2; i <= n; i++)
if(!number[i]) printf("%ld ", i);
}
This is not valid C++, if n is not a constant integral expression (yours isn't):
bool number[n+1];
It is a g++ extension, and puts the array on the call stack, which has limited size. You're overflowing it, causing an immediate program crash (no exception to recover from) so this is a bad idea even in g++.
Try
std::vector<bool> number(n+1);
(Note you'll need #include <vector> to make that work)
Also note that vector<bool> is a weird beast. Should work just fine for your usage, but to get something closer to bool[], you can also try
std::vector<char> number(n+1);
This looks wrong:
bool number[n+1];
Try either std::vector<bool> number(n+1) or bool* number = new bool[n+1]
You are trying to allocate array of n bools on stack, which might be simply to small. Try allocating on heap with std::vector or new operator.