The code is giving SIGSEGV error. How can I remove it? The code is multiplying elements of an array and modulo 109+7 at each step of multiplication.
int main()
{
int n;
int A[10];
cin >> n;
for(int i = 0; i < n; i++)
cin >> A[i];
int ans = 1;
int m = 1000000007;
for(int i = 0; i < n; i++)
{
ans = (ans * A[i]) % m;
}
cout << ans;
}
In your code the array A is declared as of 10 elements. However, afterwards the amount of elements to handle is asked to user. Also, potentially the first number enterred by the user seems to be either negative or more than 10. In this case you need to test the enterred value.
Besides that, you can use std::vector instead of the array A to be of a dynamic size. Then after the user has given the amount of elements (with the first std::cin) you can set the size of the vector. The rest code then will remain nearly the same with some cosmetical changes.
Arrays in C++ do not magically resize themselves. As a result, if the user enters a value for n of 10 or more, both loops attempt to access elements of the array A past its end. For example, if n is 13, the loops will access 13 elements of a 10 element array named A.
That is undefined behaviour. If your host system is some unix variant (e.g. linux) and the operating system detects your program accessing memory it shouldn't, it will send a SIGSEGV signal to your program, which forceably causes the program to exit. However, that is only one possible symptom of many.
Given that this is a homework exercise, I'll just say you need to work out a way to dynamically allocate an array with n elements - AFTER reading n. Using a standard container (like std::vector<int>) is one way - but, depending on what your homework requires, may not be permitted. In that case, look up operators new and delete. (No, I will not be more specific - this is your homework, not mine)
Related
I wrote the following program, trying to optimize a recursive algorithm using Dynamic Programming.
#include <bits/stdc++.h>
using namespace std;
int mini(int n, vector<int> &memory){
if(n<memory.size()){
return memory[n];
}
else{
int m = (n+1)+mini(((n-1)/2), memory)+mini(((n-1)-((n-1)/2)), memory);
memory[n]=m;
return m;
}
}
int main(){
vector<int> memory={0, 2, 5};
int t;
cin >> t;
while(t--){
int n;
cin >> n;
cout << mini(n, memory) << "\n";
}
}
The base conditions for the recursive function are already specified inside the vector, and the function does work for the base conditions. It works correctly for mini(1), mini(2), ..., mini(5). Whenever I am trying anything from mini(6) or beyond, the program just freezes.
After a bit of debugging, the problem does seem to be that the function is unable to read any of the values that we are subsequently adding into the memory vector. Which is why the following works:
mini(5) = 6 + mini(2) + mini(2) //mini(2) is pre-specified in memory vector.
mini(4) = 5 + mini(1) + mini(2) //mini(1) and mini(2) are pre-specified.
However,
mini(6) = 7 + mini(2) + mini(3) //mini(3) is not pre-specified into vector memory.
Here, mini(3) should have been added into the vector and used, but the function somehow doesn't seem to be able to do that.
It seems that the function is unable to perform recursions beyond a single level. I have no idea why, and would very much prefer some reason why this is happening.
Following insights from the comments, the problem has been solved.
There were two issues with the initial program:
Trying to insert elements beyond the current size of the vector: To fix this issue, use an if statement before inserting elements to the vector to ensure that it has the correct capacity.
if(memory.capacity()<(n+1)){
memory.resize(n+1);
}
memory[n]=m;
Using items from memory that we did not previously insert: When we are resizing memory from the previous point, we are also creating empty values at spots that we did not insert into before. For example, mini(7) would insert the values of mini(3) and mini(7) into memory. The values of mini(4), mini(5) and mini(6) would remain 0. Later when we use the function, the values of mini(4), mini(5) and mini(6) would be found in the memory to be 0, and be used as such, leading to incorrect answers.
Fixing both errors, the revised function looks like this:
int mini(int n, vector<int> &memory){
if(n<memory.size() && memory[n]!=0){
return memory[n];
}
else{
int m = (n+1)+mini(((n-1)/2), memory)+mini(((n-1)-((n-1)/2)), memory);
if(memory.capacity()<(n+1)){
memory.resize(n+1);
}
memory[n]=m;
return m;
}
}
I have gathered a large amount of extremely useful information from other peoples' questions and answers on SO, and have searched duly for an answer to this one as well. Unfortunately I have not found a solution to this problem.
The following function to generate a list of primes:
void genPrimes (std::vector<int>* primesPtr, int upperBound = 10)
{
std::ofstream log;
log.open("log.txt");
std::vector<int>& primesRef = *primesPtr;
// Populate primes with non-neg reals
for (int i = 2; i <= upperBound; i++)
primesRef.push_back(i);
log << "Generated reals successfully." << std::endl;
log << primesRef.size() << std::endl;
// Eratosthenes sieve to remove non-primes
for (int i = 0; i < primesRef.size(); i++) {
if (primesRef[i] == 0) continue;
int jumpStart = primesRef[i];
for (int jump = jumpStart; jump < primesRef.size(); jump += jumpStart) {
if (primesRef[i+jump] == 0) continue;
primesRef[i+jump] = 0;
}
}
log << "Executed Eratosthenes Sieve successfully.\n";
for (int i = 0; i < primesRef.size(); i++) {
if (primesRef[i] == 0) {
primesRef.erase(primesRef.begin() + i);
i--;
}
}
log << "Cleaned list.\n";
log.close();
}
is called by:
const int SIZE = 500;
std::vector<int>* primes = new std::vector<int>[SIZE];
genPrimes(primes, SIZE);
This code works well. However, when I change the value of SIZE to a larger number (say, 500000), the compiler returns a "segmentation error." I'm not familiar enough with vectors to understand the problem. Any help is much appreciated.
You are accessing primesRef[i + jump] where i could be primesRef.size() - 1 and jump could be primesRef.size() - 1, leading to an out of bounds access.
It is happening with a 500 limit, it is just that you happen to not have any bad side effects from the out of bound access at the moment.
Also note that using a vector here is a bad choice as every erase will have to move all of the following entries in memory.
Are you sure you wanted to do
new std::vector<int> [500];
and not
new std::vector<int> (500);
In the latter case, you are specifying the size of the vector, whose location is available to you via the variable named 'primes'.
In the former, you are requesting space for 500 vectors, each sized to the default that the STL library wants.
That would be something like (on my system : 24*500 bytes). In the latter case, 500 length vector(only one vector) is what you are asking for.
EDIT: look at the usage - he needs just one vector.
std::vector& primesRef = *primesPtr;
The problem lies here:
// Populate primes with non-neg reals
for (int i = 2; i <= upperBound; i++)
primesRef.push_back(i);
You only have N-2 elements in your vector pushed back, but then try to access an element at N-1 (i+jump). The fact that it did not fail on 500 is just dumb luck that the memory being overwritten was not catastrophic.
This code works well. However, when I change the value of SIZE to a larger number (say, 500000), ...
That may blow your stack, and be to big allocated with it. You need dynamic memory allocation for all of the std::vector<int> instances you believe to need.
To achieve that, simply use a nested std::vetcor like this.
std::vector<std::vector<int>> primes(SIZE);
instead.
But to get straight on, I seriously doubt you need number of SIZE vector instances to store all of the prime numbers found, but just a single one initialized like this:
std::vector<int> primes(SIZE);
Today I tried to program the Sieve of Eratosthenes and it works as far as it provides me with the prime numbers. But I have a problem with the dynamic array I don't understand.
First problem: As soon as I try to enter a "big" value for n (for example 120), the program crashes, it doesn't even allocate the memory.
Second problem: If I enter a value like 50 it is able to give out the correct prime numbers but crashes before it deletes the array.
Third problem: If I enter a very small value like 5 it is able to execute the entire program, it gives out the correct numbers and deletes the memory.
But I don't understand why it acts so differently. 120 boolean values can't crash my memory, at least I think so. And why isn't it able to delete an array of 50 values but is actually able to delete an array of 5 values?
Can anyone tell me what's the problem?
int n;
cin >> n;
n=n+1;
bool *feld = new bool[n];
for(int i=2;i<n;i++)
{
int j=i*i;
feld[j]=true;
for(;j<n;j+=i)
feld[j]=true;
}
for(int i=2;i<n;i++)
if(!feld[i])
cout << i << endl;
else;
delete[] feld;
feld = NULL;
Your problem is here:
int j=i*i;
feld[j]=true;
there is no check as to whether j < n so you are stomping over unallocated memory when j >= n.
This code is wrong
bool *feld = new bool[n];
for(int i=2;i<n;i++)
{
int j=i*i;
feld[j]=true;
...
}
Suppose n == 10 and i == 9, then j == 81 but you only have 10 elements in your bool array.
This is how it works when you write bugged programs, sometimes it seems to work, it might even give the right answer, other times it will crash. This is a very important lesson, and you're actually lucky to have learned it early.
Actually It's not just that feld[j]=true; is causing the error.
Also, you don't need that line at all before the loop.
because, it's the first case inside the loop.
I have written some code, here is a snippet of it is:
int num[8],n=0;
for (n = 0; n<8; n++)
{
char temp = binnum[n];
num[n] = atoi(&temp);
cout << num[n];
}
It doesn't gives any error, but I do get a warning. When I run it on C++, it gives Run Time Check Failure - The variable n is being used without being initialized.
After that, it doesn't run any further and the program closes. Is there any way to ignore this error? Because if I initialize n, it gives the wrong answer. For example, if answer is 101011, it will give 10101100, which is wrong.
Initialize n as #anthares pointed out and increment it at the end of the loop so your loop actually works.
int number[8];
int n = 0;
do
{
char temp = binnum[n];
number[n] = atoi(&temp);
cout << number[n];
n++;
} while (n<8);
Your main problem (after all the edits) is that atoi takes a null-terminated char array (C-style string). The address of a single char variable does not make a C-style string.
To convert a single character in range ['0'...'9'] to a corresponding number use:
number[i] = temp - '0';
possibly having checked that temp contains a digit character.
Give a value to your vairable n before using it int number [8], n=0 for example. Otherwise, it is "not defined behavior" what is the value of n and how many iterations you will do in your cycle.
Also, As it is written your loop will go forever since you never change the value of n ...
You are using n before it is assigned a value. You need to ensure that n is initialized (to 0, maybe) before you begin to reference it in your code. You do not want to ignore this error.
Try something like this:
const int count = 8;
int number[count];
for (int i=0; i < count; i++)
{
char temp = binnum[i];
number[i] = atoi(&temp);
cout << number[i];
}
what? you never assign any value to n.
and even if you will for example do int number[8],n=0; you never change n's value you you will end up with an infinite loop.
You should really initialize n (and also increment it, for that matter).
You are probably running a debug build of your application. In this case, the variable is probably always initialized with the same value. This is why you see the result you expect. It seems to behave correct purely by accident.
As soon as your application is built in release mode, n may have a different value each time the program is run and thus the output will be unpredictable.
This is what happens when you have undefined behavior in your program.
I'm running CodeBlocks on the MingW compiler in an XP virtual machine. I wrote in some simple code, accessible at cl1p , which answers the algorithm question at CodeChef (Well it only answers it partly, as I have not yet included the loop for multiple test cases.
However, my problem is, that while running it in debug mode, it gives the correct output of 5, for the input:
3
1
2 1
1 2 3
However, when I build and run it, it gives the absurd, huge output 131078, what seems like garbage to me. I do not understand how the hell this is happening, but am guessing it's something to do with the dynamic memory allocation. What's the problem here, and how can I fix it? I even ran it through the online compiler at BotSkool, and it worked fine. After adding the loop for test cases, the code even worked correctly on CodeChef!
#include <iostream>
using namespace std;
int main()
{
// Take In number of rows
int numofrows;
cin >> numofrows;
// Input Only item in first row
int * prevrow;
prevrow = new int[1];
cin >> prevrow[0];
// For every other row
for (int currownum = 1; currownum < numofrows; currownum++)
{
// Declare an array for that row's max values
int * currow;
currow = new int[currownum+1];
int curnum;
cin >> curnum;
// If its the first element, max is prevmax + current input
currow[0] = prevrow[0] + curnum;
// for every element
int i = 1;
for (; i <= currownum; i++)
{
cin >> curnum;
// if its not the first element, check whether prevmax or prev-1max is greater. Add to current input
int max = (prevrow[i] > prevrow[i-1]) ? prevrow[i] : prevrow[i-1];
// save as currmax.
currow[i] = max + curnum;
}
// save entire array in prev
prevrow = new int[i+1];
prevrow = currow;
}
// get highest element of array
int ans = 0;
for (int j=0; j<numofrows; j++)
{
if (prevrow[j] > ans)
{
ans = prevrow[j];
}
}
cout << ans;
}
Run the code through Valgrind on a Linux machine and you'll be amazed at how many places your code is leaking memory.
If you are taking the hard road of managing your memory, do it well and 'delete' all the new-allocated memory before allocating more.
If, on the other hand, you prefer the easy road, use a std::vector and forget about memory management.
For one thing, this:
//save entire array in prev
prevrow = new int [i+1];
prevrow = currow;
copies the pointer, not the whole array.
In your loop, you have this line
int max = (prevrow[i]>prevrow[i-1])?prevrow[i]:prevrow[i-1];
On the first iteration of the main loop, when currownum == 1, the loop containing this line will be entered, as i is initialized to 1. But on the first iteration, prevrow only has one element and this line tries to access prevrow[1]. In a debug build, the memory simply gets initialized to zero, but in a normal build, you get some garbage value that just happened to be in the memory, leading to the result you see.
Pretty much always, when you get garbage values in a normal build, but everything is fine in a debug build, you are accessing some uninitialized memory.
Also, your program is leaking memory like crazy. For instance, you don't need to assign any result of new inside the loop to prevrow because right after that you change prevrow to point to another block of allocated memory. Also, you should call delete for any memory that you are no longer using.