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.
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;
}
}
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)
As stated above my program works in Debug and Release without debug (ctrl + F5) however does not work in simply Release.
Just to clarify I have already checked to see if I have some uninitialized variables and I haven't (to the best of my knowledge anyway but I have spent quite some time looking).
I believe to have localized the issue and what I have come across is, in my opinion, very bizarre. First I set up the break points as shown in the picture below:
Then I run the program in release. And instantly the top break point moves:
I found this extremely odd. Now note the number 6302 assigned to 'n'. This number is correct and what I hoped to pass through. Now watch as I continue through the program.
We are still in good shape but then it turns for the worst.
'n' changes to 1178521344, which messes up the rest of my code.
Would someone be able to shed some light on the situation, and even better, offer a solution.
Thanks,
Kevin
Here is the rest of the function if it helps:
NofArr = n;
const int NA = n;
const int NAless = n-1;
double k_0 = (2*PI) / wavelength;
double *E = new double[NAless]; // array to hold the off-diagonal entries
double *D = new double[NA]; // array to hold the diagonal entries on input and eigenvalues on output
int sizeofeach = 0;
trisolver Eigen;
int* start; int* end;
vector< vector<complex <double>> > thebreakup = BreakUp(refidx, posandwidth, start, end);
for(int j = 0; j < (int)thebreakup.size(); j++){
// load the diagonal entries to D
for(int i =0; i < (int)thebreakup[j].size(); i++){
D[i] = -((double)2.0/(dx*dx)) + (k_0*k_0*thebreakup[j][i].real()*thebreakup[j][i].real());
}
// load the off diagonal
for(int i = 0; i < (int)thebreakup[j].size(); i++){
E[i] = (double)1.0 / (dx*dx);
}
sizeofeach = (int)thebreakup[j].size();
double *arr1= new double[sizeofeach];
arr1 = Eigen.EigenSolve(E, D, sizeofeach, mode);
complex <double> tmp( PhaseAndAmp[j][1]*cos(PhaseAndAmp[j][0]), PhaseAndAmp[j][1]*sin(PhaseAndAmp[j][0]));
// rebuild the break up with the mode
for(int i = 0; i < (int)thebreakup[j].size(); i++){
thebreakup[j][i] = (complex<double>(arr1[i],0.0)) * tmp ;
}
delete []arr1;
}
vector<complex<double>> sol = rebuild(thebreakup, start, end);
delete [] E;
delete [] D;
delete [] start;
delete [] end;
return sol;
I'm writing this as an answer, because it's way harder to write as a comment.
What strikes me immediately is the array "arr1"
First you allocate new memory and store a pointer to it in the variable arr1
double *arr1= new double[sizeofeach];
Then, immediately, you overwrite the address.
arr1 = Eigen.EigenSolve(E, D, sizeofeach, mode);
Later, you delete something. Is it safe?
delete []arr1;
It's not the double array you allocated, but something eigensolve returned. Are you sure you have the right to delete it? Try removing the delete here. Also, fix the memory leak too, by removing allocation in the first line I gave.
What worries me even more is that the "this" pointer changes. There is some nasty problem somewhere. At this point, your program has already been corrupted. Look for the issue somewhere else. Valgrind would be a GREAT tool if you can try to compile under linux.
It seems that there is some sort of code optimization going on in your program. It is not always easy to debug optimized code step-by-step since the optimization may reorder instructions.
I cannot see why the fact that 'n' changes to an apparently uninitialized value would be the root cause of the problem, since 'n' is anyways no longer used in your function. Seems like the memory is simply been released as part of the optimization.
I have discovered my mistake. Earlier in the program I was comparing pointers, not what they were pointing at. A stupid mistake but one I wouldn't have spotted without a long debugging session. My boss explained that the information given at the bottom of Visual Studio whilst in release mode cannot be trusted. So to "debug" I had to use std::cout and check variables that way.
So here is the mistake in the code:
if(start > end){
int tmp = start[i];
start[i] = end[i];
end[i] = tmp;
}
Where start and end were defined earlier as:
int* start = new int[NofStacks];
int* end = new int[NofStacks];
And initialized.
Thanks to all those who helped and I feel I must apologise for the stupid error.
The Fix being:
if(start[i] > end[i]){
int tmp = start[i];
start[i] = end[i];
end[i] = tmp;
}
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.
EDIT: Pastebin links to the entirety of the code at the bottom
for my CS215 course, I was given a class called String215 which is a basic string class to help in the understanding of dynamic memory allocation and pointer arithmetic with char arrays.
The class was given to me in a very basic skeleton form with prototypes but no implementations, along with a test function to test my implementations. I CAN NOT use any C String functions in this assignment.
The part of the program which is troubling is the append function, which just appends a parameter string215 object to the end of the current string215 object.
// Add a suffix to the end of this string. Allocates and frees memory.
void string215::append(const string215 &suffix)
{
char *output = new char[str_len(data)+suffix.length()+1];
for(int x = 0; x < str_len(data); x++) {
*output = *data;
output++;
data++;
}
for(int x = 0; x < suffix.length(); x++) {
*output = suffix.getchar(x);
output++;
}
*output = '\0';
output -= (str_len(data)+suffix.length()+1);
delete[] data;
data = output;
}
This portion of the code is tested in the 13th test of the test function as shown here:
string215 str("testing");
...
// Test 13: test that append works in a simple case.
curr_test++;
string215 suffix("123");
str.append(suffix);
if (strcmp(str.c_str(), "testing123") != 0) {
cerr << "Test " << curr_test << " failed." << endl;
failed++;
}
Here is the description of the append class:
Add the suffix to the end of this string. Allocates a new, larger, array; copies the old contents, followed by the suffix, to the new array; then frees the old array and updates the pointer to the new one.
My program aborts at the very end of the append function execution with the error message:
Debug Assertion Failed!
Program: [Source path]\dbgdel.cpp
Line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
...
Abort || Retry || Ignore
I'm fairly certain it has something to do with my very poor memory management. I know it's not a lot to go on, but I've been struggling with this for hours on end and can't seem to figure it out.
Here's a pastebin of the .cpp and .h file for this program
string215.cpp: http://pastebin.com/Xh2SvDKJ
string215.h: http://pastebin.com/JfAJDEVN
Any help at all is greatly appreciated!
Thanks,
RAW-BERRY
You are changing data pointer before delete[]. You need to delete[] exactly the same value you got from new[].
Also, you are incrementing output pointer str_len(data)+suffix.length() times, and you take it back by str_len(data) + suffix.length() + 1.
I would use separate variables for iteration to solve these problems.
You increment output exactly str_len(data) + suffix.length() times. Note that you don't increment output after *output = '\0';.
So to go back to the start, you should use:
output -= (str_len(data) + suffix.length());
By the way, some of the code is not very efficient. For example, getchar uses a loop instead of simply returning data[index]. You use getchar in append, which means that the performance isn't great.
EDIT: As zch says, you use delete[] data after modifying data, but note that even before that you use str_len(data) after modifying data (when deciding how many bytes to go skip back), so the calculation is wrong (and my suggestion above is also wrong, because str_len(data) is now zero).
So I think your problem is with the line
for(int x = 0; x < str_len(data); x++) {
Notice that the size of 'data' is changing at each iteration of the loop. As you increment 'x', you are decreasing the length of 'data'. Suppose 'data' is a string holding "hello": in the first iteration of the loop x=0 and str_len(data)=5; in the second iteration x=1 and str_len(data)=4. Thus the for loop executes half as many times as you need it to and 'data' does not end up pointing to the end of the data string