Getting a C++ segmentation fault - c++

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.

Related

Adding even / odd elements in *argv[] to arrays

I'm fairly new to C++ and I'm making a simple program which takes values and units as system arguments and converts them all to a single unit. The command line execution and input goes something like this:
./unit_conv 3 feet 5 inches centimeters
The values and units are separated by spaces, and the final argument is the unit I want to convert everything to.
My approach to get input is to add all even elements of *argv[] before the last element to an integer array called 'values', and add all odd ones to a character pointer array called 'units'. Below is my attempted implementation:
if (argc % 2 == 0) {
char * desiredUnit = argv[argc - 1];
int values[argc];
char * units[argc];
int j;
int k;
for (int i = 1; i < argc; i++) {
if (i % 2 == 1) {
values[j] = atoi(argv[i]);
j++;
}
else {
units[k] = argv[i];
k++
}
}
}
Upon the execution I mentioned above, I get the following:
Segmentation fault (core dumped)
I know the seg fault is occurring within my for loop. I don't see how the program is attempting to access restricted memory, though. I've been stuck with this one for quite awhile.
Hopefully I provided enough info, but if my question is too vague please let me know.
Thanks!
Have you tried using STL?
std::vector<std::string> units{};
std::vector<int> values{};
for (std::size_t i {1}; i < argc; ++i) {
if (i % 2 == 0) {
units.push_back(std::string{argv[i]});
} else {
values.push_back(std::atoi(argv[i]));
}
}

Array doesn't print anything on executing code

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.

Segmentation Fault while accessing 2-dimensional vector

I am trying to access a specific position of a 2-dimensional vector. I declared the vector and initialized it, and on printing it out, the vector seems properly declared. Now, when I try to access the vector from an if statement in a class function, I get a segmentation fault.
class cache{
vector<vector<int>> v;
v.resize(5);
for(z = 0; z < v.size(); z++){
v[z].resize(5);
}
for(x = 0; x < v.size(); x++){
for(y = 0; y < v[x].size(); y++){
v[x][y]=5;
}
}
for(x = 0; x < v.size(); x++){
for(y = 0; y < v[x].size(); y++){
cout<<v[x][y]<<" ";
}
cout<<"\n";
}
int readCache(int a){
int value = a>>15;
int index = a % (unsigned long)pow(2,15);
// Do I not try to access using the size?
for(x = 0; x < v.size(); x++){
cout<<v[x][index]<<endl;
// Or do I use this alternate line?
// cout<<v[index][x]<<endl;
}
}
};
I can't find a proper error message either.
The vector's sizes change depending on the parameters passed to it.
For now, its a 1x2048 vector.
Simple out of bound access. You have a 5x5 matrices, but you are trying to get an element outside:
int value = a>>15;
int index = a % (unsigned long)pow(2,15); // This is also very not efficient
The index is most definitely wrong.
EDIT 2: Segmentation Faults appear to be fixed.
Since this is a homework question, I am unable to post the complete online for fear of plagiarism issues.
However, the readCache function essentially checks if the address value is present in the nested vector. Now, it seems you cannot directly compare like
vec[a][b] = value;
It worked when I assigned the value at the desired position to a temporary variable and then compared to the given value. Like this:
int temp = vec[a][b];
if(temp == value){
// do something
}
EDIT: This hasn't worked yet.
#PaulMcKenzie's comment about accessing vectors helped me get rid of segmentation faults and I started running into out_of_range errors as they predicted.
Then, in the readCache function, I was passing a 32-bit bitset to access a cache. But I don't actually need to access the data byte in a cache block, so the modulus had three extra bits which I didn't need. The range of the modulus function is 0 to (value - 1), so at some point it would exceed the size of the vector.
It is a homework problem.

SIGABRT error in C++

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.

Program stops working when making big table (2'000'000+)

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.