Heap block modified past request error in C++ - c++

I have and QT application with class Solver that solve some numeric problem (Bairstow method for finding roots of the polynomial by finding its distribution to trinomials) but while for smaller instances (5 parameters, in array tabA) it work fine, but when I tried this for larger instances (7 parameters) application crashed.
After I run the debugger I get the following message:
Heap block at 02989F58 modified at 02989F80 past request 20
I'm not exactly sure what is about (well I suppose I get stack overflow but I'm not sure where and how) but it points to line delete[] Q; delete[] W; here is how debugger pointed it:
And here is code of that class methods (the error occurs in main method int Bairstow(*parameters*), which work on class fields and returns number which indicate is solution was found, is not existing or can't be found in given number of iteration)
Here's the main method:
int solver::Bairstow(int stopien,double const *tabA, double *tabP,double *tabR, double eps, int N, double p_,double r_)
{
int i,q, Iter, indpziel=0;
i=stopien;
while(i>=0 && tabA[i]==0)
{
i--;
}
if (i<2) { return 1; }
double *A=new double[stopien +1]
for (i=0;i<=stopien;i++)
{
A[i]=tabA[i];
}
double *Q=new double[stopien-1 +1];
double *w=new double[stopien-3 +1];
double Reszta[2];
double dqdp[2], dqdr[2];
double p,r, a,b,c,d;
while (stopien>=2)
{
p=p_, r=r_;
Iter=O;
do
{
PodzielWiel(stopien,A,p,r,Q,Reszta);
if (fabs(Reszta[1])<eps && fabs(Reszta[0])<eps)
{
break;
}
PodzielWiel(Stopien-2,Q,p,r,W,dqdr);
for (i=Stopien-2;i>=0;i--)
{
Q[i+1]=Q[i];
}
Q[0]=0;
PodzielWiel(Stopien-1,Q,p,r,W,dqdp);
q=LiczMOdwrotna(dqdp[0],dqdr[0],dqdp[1],dqdr[1],a,b,c,d);
if (q==1)
{
delete[] Q;
delete[] W;
return 2;
}
p = p-(a*Reszta[0]+b*Reszta[1]);
r = r-(c*Reszta[0]+d*Reszta[1]);
} while (++Iter<N);
if (Iter==N) return 3;
tabP[IndDziel]=p;
tabR[IndDziel]=r;
IndDziel++;
Stopien-=2;
for (i=0;i<=Stopien;i++)
{
A[i]=Q[i];
}
}
delete[] Q; delete[] W; //that's the line debugger pointed to
return 0;
}
And two helper methods:
for polynomial division (by trinomial x^2-px-r)
int solver::PodzielWiel(int stopien,double const *tabA, double p,double r, double *Q,double *R)
{
if (Stopien<O) return 1;
int i;
for (i=0;i<=stopien-2;i++)
{
Q[i]=0;
}
while (stopien>=0 && tabA[stopien]==0)
{
stopien--;
}
if (stopien<2)
{
R[0]=tabA[0];
R[1]=tabA[1];
return 0;
}
double *A=new double[Stopien +1];
for (i=0;i<=stopien;i++)
{
A[i]=tabA[i];
}
Q[stopien-2]=A[stopien];
if (stopien>2)
{
for(i=stopien; i>1; i--)
{
Q[i-2]=A[i];
A[i-1]+=Q[i-2]*p;
A[i-2]+=Q[i-2]*r;
}
R[1]=A[1];
R[0]=A[0] ;
}
else
{
R[1]=A[1]+p*Q[0] ;
R[0]=A[0]+r*Q[0] ;
}
delete [] A;
return 0;
}
for inversing the 2x2 matrix(first 4 parameters are inputs and next 4 outputs as it):
int Solver::LiczMOdwrotna(double x,double y,double w,double z, double &a,double &b,double &c,double &d)
{
if (x*z==y*w)
{
return 1;
}
if (x*w!=0)
{
c=1/(y-z*x/w);
a=-z*c/w;
d=1/(z-y*w/x);
b=-y*d/x;
}
else if (y*z!=0)
{
a=1/(x-w*y/z);
c=-w*a/z;
b=1/(w-z*x/y);
d=-x*b/y;
}
else if (x==0 && z==0)
{
c=1/y;
d=0;
a=0;
b=1/w;
}
else if (y==0 && w==0)
{
a=1/x;
b=0;
c=0;
d=1/z;
}
return 0;
}
And sory for maybe poor formatting but I have to use OCR software as copying from QT creator was impossible... even after using show in explorer, save file as txt in new localization (to make it visible outside QT Creator) and then doing it again... I still couldn't copy anything...

Related

Getting wrong answer in a DP problem although implementation looks correct

I was trying to solve Reduce String on codechef which says
Give a string s of length l, and a set S of n sample string(s). We do reduce the string s using the set S by this way:
Wherever Si appears as a consecutive substring of the string s, you can delete (or not) it.
After each deletion, you will get a new string s by joining the part to the left and to the right of the deleted substring.
I wrote a recursive function as follows:-
Basically what i am doing in my code is either don't delete the character or delete it if it is part of any substring but it is giving wrong answer.
#include <bits/stdc++.h>
using namespace std;
#define mx 255
int dp[mx];
unordered_map<string,int> sol;
void init(int n)
{
for(int i=0;i<n;i++)
{
dp[i]=-1;
}
}
int solve(string str,int low,int high,vector<string> smp)
{
if(low>high)
{
return 0;
}
if(dp[low]!=-1)
{
return dp[low];
}
int ans=1+solve(str,low+1,high,smp);
for(int i=low;i<high;i++)
{
string tem=str.substr(low,i-low+1);
for(int j=0;j<smp.size();j++)
{
cout<<"low i high str"<<low<<" "<<i<<" "<<high<<" "<<smp[j]<<" "<<tem<<endl;
if(tem.compare(smp[j])==0)
{
ans=min(ans,solve(str,i+1,high,smp));
}
}
}
return dp[low]=ans;
}
signed main()
{
sol.clear();
string str;
vector<string> smp;
int n;
cin>>str;
cin>>n;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
smp.push_back(tem);
}
int len=str.length();
init(len+1);
cout<<solve(str,0,len-1,smp)<<endl;
return 0;
}
PS:
link to the question
This question is toughest(seen so far) and most beautiful(again seen so far) question based on DP ON INTERVALS.
The initial code would definitely not work since it only considers single pass on the string and would not consider remaining string after deleting the patterns again and again.
There are 3 cases:-
Case 1 Either character is not deleted.
Case 2It is deleted as a part of contiguous substring.
Case 3It is deleted as a part of subsequence that matches any word given in the set of patterns and everything that is not part of that subsequence is deleted first as a substring(which again belongs to set of words).
The third part is the most tricky and requires enough thinking and is even tougher to implement too.
So for every substring we need to check whether this substring can be completely destroyed or not.
The function compute_full_recur() is the function that ensures that whether substring can be deleted either in Case 2 or Case 3.
The function compute_full takes care of Case 1.And finally this code will not run on codechef link since all the function are recursive with memoization but to verify the code is working i Have run it on Problem Reducto of Hackerrank which is exact similar with lower constraints.Download test cases and then run on test cases on your PC for verifying.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
#define mx 252
#define nx 40
bool full[mx][mx],vis[mx][mx],full_recur[mx][mx][nx][nx];
int ans[mx];
void init()
{
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
full[i][j]=false,vis[i][j]=false;
}
}
for(int i=0;i<mx;i++)
{
ans[i]=-1;
}
for(int i=0;i<mx;i++)
{
for(int j=0;j<mx;j++)
{
for(int k=0;k<nx;k++)
{
for(int l=0;l<nx;l++)
{
full_recur[i][j][k][l]=false;
}
}
}
}
}
bool compute_full_recur(string str,int low,int high,vector<string> pat,int idx,int len)
{
if(low>high&&len==pat[idx].length())
{
return true;
}
if(low>high&&len<pat[idx].length())
{
full_recur[low][high][idx][len]=false;
return false;
}
if(str[low]==pat[idx][len]&&compute_full_recur(str,low+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
for(int i=low+1;i<=high;i++)
{
if(str[low]==pat[idx][len]&&full[low+1][i]&&compute_full_recur(str,i+1,high,pat,idx,len+1))
{
return full_recur[low][high][idx][len]=true;
}
}
full_recur[low][high][idx][len]=false;
return false;
}
void compute_full(string str,int low,int high,vector<string> pats)
{
if(low>high)
{
return;
}
if(vis[low][high])
{
return;
}
vis[low][high]=true;
compute_full(str,low+1,high,pats);
compute_full(str,low,high-1,pats);
for(int i=0;i<pats.size();i++)
{
if(!full[low][high])
full[low][high]=compute_full_recur(str,low,high,pats,i,0);
}
}
int compute_ans(string str,int low,int high)
{
if(low>high)
{
return 0;
}
if(ans[low]!=-1)
{
return ans[low];
}
int sol=1+compute_ans(str,low+1,high);
for(int i=low+1;i<=high;i++)
{
if(full[low][i]==true)
{
sol=min(sol,compute_ans(str,i+1,high));
}
}
return ans[low]=sol;
}
signed main()
{
int t;
cin>>t;
while(t--)
{
string str;
int n;
vector<string> pats;
cin>>n>>str;
for(int i=0;i<n;i++)
{
string tem;
cin>>tem;
pats.push_back(tem);
}
init();
compute_full(str,0,str.length()-1,pats);
cout<<compute_ans(str,0,str.length()-1)<<endl;
}
return 0;
}

Different results with same function and argument in c++ code

I've made a function that calculate chebyshev moment for an image, here is the main code. I have different results with same image, and every time I run I get new values. Here is the functions and the main code.
float calcul_ro(int p,int N)
{int i; float ro_p=1,float_N=(float)N;
if (p==0)
ro_p=(float)N;
else {
for (i=1;i<=p;i++)
ro_p=ro_p*(1-((i*i)/(N*N)));
ro_p=(ro_p*float_N)/(2*p+1);
}
return ro_p;
}
///______________________________________________________________________________///
float calcul_tp(int x,int p,int N,float tp_1,float tp_2)
{float tp, float_N=(float)N;
if (p==0)
tp=1;
else if(p==1)
tp=2*x+1-N;
else
{ //tp=((2*p-1)*tp_1)-((p-1)*(1-(pow((float)(p-1),2)/pow(float_N,2)))*tp_2);
tp=((2*p-1)*tp_1)-(((p-1)*(1-((p-1)*(p-1))/(N*N)))*tp_2);
tp=tp/p;}
return tp;
}
///______________________________________________________________________///
float *chebychev_moment(Mat image,int N)
{int p,q,x=0,y=0,i=0,j,compt=0,hml=0; float rslt,alpha_p,alpha_q,beta_p,beta_q,ro_p=1,ro_q=1,tp,tq;
float *vect=new float[55];
float tp_moins_1[100][100], tp_moins_2[100][100], tq_moins_1[100][100],tq_moins_2[100][100];
///******************************************************************
///initialisation de tp_moins_1
for(i=0;i<100;i++)
{
for(j=0;j<100;j++)
tp_moins_1[i][j]=1;
}
///************************************************************************
for (p=0;p<9;p++)
{
for(i=0;i<100;i++)
{
for(j=0;j<100;j++)
tq_moins_1[i][j]=1;
}
for(q=0;q<=9-p;q++)
{
ro_p=calcul_ro(p,N);
ro_q=calcul_ro(q,N);
///************************************
for (x=0;x<image.rows;x++)
{ y=0;
tp=calcul_tp(x,p,N, tp_moins_1[x][y], tp_moins_2[x][y]);
tp_moins_2[x][y]=tp_moins_1[x][y];
tp_moins_1[x][y]=tp;
for(y=0;y<image.cols;y++)
{ if(image.at<int>(x,y)!=0)
{tq=calcul_tp(y,q,N,tq_moins_1[x][y],tq_moins_2[x][y]);
tq_moins_2[x][y]=tq_moins_1[x][y];
tq_moins_1[x][y]=tq;
rslt=rslt+tp*tq*image.at<int>(x,y);}
}
}
///************************
rslt=rslt*(1/(ro_p*ro_q));
printf("rslt %d ,p=%d,q=%d, =%f \n",hml,p,q,rslt);
vect[compt]=rslt;
compt++;
rslt=0;
}}
return vect;
}
///______________________________________________________________________________///
int main()
{ Mat image=imread("2_.png",CV_LOAD_IMAGE_GRAYSCALE);
float *vect=new float[55], *vect2=new float[55];
vect=chebychev_moment(image,100);
Mat image2=imread("2_.png",CV_LOAD_IMAGE_GRAYSCALE);
vect2=chebychev_moment(image2,100);
//function that copy the vector in a file
write_on_file(vect,"vector_image3.txt");
write_on_file(vect2,"vector_image4.txt");
return 0;}
Can someone please help me?
Looks like rslt in chebychev_moment is used before it is set. Probably you forgot to initialise it to 0. alpha_p, alpha_q, beta_p, beta_q are not used at all.

Different output when set different breakpoints

I just wrote a code to build a Huffman Tree using MinHeap. When testing I want to output its traversal result.
The algorithm is simple, but my code can't get the right answer. It's strange that the output was different when I set different breakpoints. For instance, it depends on if I set a break point in the loop, such as line 165 input_list.insert(*parent);.
The test input was
4 //number of nodes.
1 1 3 5 //weight of each node.
and the output when debugging it with a breakpoint in the loop is
5
10
1
2
1
5
3
that is correct. But when I just run it without debug, it even didn't have any output. Does anyone know how to explain it?
#include <iostream>
#include <vector>
using namespace std;
#define max_size 100
int sum=0;
class huffman_node
{
public:
int weight;
huffman_node* left_child;
huffman_node* right_child;
huffman_node(){}
huffman_node(int w, huffman_node* l, huffman_node* r):
weight(w),left_child(l),right_child(r) {}
};
vector <huffman_node> node_list;
class minheap
{
public:
minheap()
{
heap=new huffman_node [max_size];
current_size=0;
}
~minheap()
{
delete []heap;
}
void siftdown(int start, int m)
{
int i=start;
int j=2*i+1;
huffman_node temp=heap[i];
while(j<=m)
{
if(j<m && heap[j+1].weight<heap[j].weight)
{
++j;
}
if(temp.weight<=heap[j].weight)
{
break;
}
else
{
heap[i]=heap[j];
i=j;
j=2*i+1;
}
}
heap[i]=temp;
}
void siftup(int start)
{
int j=start;
int i=(j-1)/2;
huffman_node temp=heap[j];
while(j>0)
{
if(heap[i].weight<=temp.weight)
{
break;
}
else
{
heap[j]=heap[i];
j=i;
i=(j-1)/2;
}
heap[j]=temp;
}
}
bool insert(const huffman_node& input)
{
if(current_size==max_size)
{
cout<<"minheap full"<<endl;
return false;
}
heap[current_size]=input;
siftup(current_size);
++current_size;
return true;
}
bool remove_min(huffman_node& output)
{
if(!current_size)
{
cout<<"minheap empty"<<endl;
return false;
}
output=heap[0];
heap[0]=heap[current_size-1];
--current_size;
siftdown(0,current_size-1);
return true;
}
private:
huffman_node* heap;
int current_size;
};
void route_length(huffman_node* &root,int depth)
{
if(root!=NULL)
{
// if(root->left_child==NULL&&root->right_child==NULL)
// {
// sum+=depth*root->weight;
// }
route_length(root->left_child,depth+1);
cout<<root->weight<<endl;
route_length(root->right_child,depth+1);
}
else
{
return;
}
}
int main()
{
minheap input_list;
int n;
cin>>n;
for(int i=0;i<n;++i)
{
int key;
cin>>key;
huffman_node input(key,NULL,NULL);
input_list.insert(input);
cin.get();
}
huffman_node* root;
for(int i=0;i<n-1;++i)
{
huffman_node* parent;
huffman_node out1;
huffman_node out2;
input_list.remove_min(out1);
input_list.remove_min(out2);
node_list.push_back(out1);
node_list.push_back(out2);
parent=new huffman_node(out1.weight+out2.weight,&node_list[node_list.size()-2],&node_list[node_list.size()-1]);
input_list.insert(*parent);
root=parent;
}
route_length(root,0);
// cout<<sum<<endl;
return 0;
}
The problem is that you are using pointers to elements of a vector<huffman_node> and storing these in your data structure (i.e. left and right members of the huffman_node object).
The thing that is randomly killing your program is that std::vector moves values around in memory when you append to it. The contents of the elements of the vectors are preserved, but the location is not. Once it moves the elements, the memory where the vector used to be can be overwritten by whatever (i.e. gdb needs heap memory too) and now the pointers are pointing to garbage.
As a quick sanity check, you can make your code not crash by reserving space in your node_list by calling
node_list.reserve(max_size*2);
in the beginning of main. This is not the right way of developing this piece of code further, but should illustrate the problem.
It would be better if your node_list was a vector<huffman_node*> instead. Or if you changed the left/right members to be vector indices instead of pointers.

Prime numbers in an dynamic array

I've a program which inserts all prime numbers up to a specific number in an array.
The calculation is correct. My problems are the function parameters and the transfer of my dynamic array to the function. My function doesn't modify my array.
Please take a look at the code:
#include <iostream>
using namespace std;
int primeinlesen(int *i);
int primarrayspeicherung (int *primarray,int *bis);
int main()
{
int reload=1;
while(reload==1)
{
int bis=0,*primarray,valcounter;
primeinlesen(&bis);
valcounter=primarrayspeicherung(primarray,&bis);
for(int i=0;i<valcounter;i++)
{
cout<<i<<". Primzahl: "<<primarray[i]<<"\n";
}
delete [] primarray;
cout<<"Anzahl Primzahlen: "<<valcounter<<endl;
cout<<"Erneute Berechnung?(Ja(1) oder Nein(0))";
cin>>reload;
}
return 0;
}
int primeinlesen(int *i)
{
cout<<"Bis zu welchem Wert moechten SiePrimzahlen ausgegeben,haben(max.500)";
cin>>*i;
if(*i>500)
{
cout<<"Wert zu hoch...";
}
return 0;
}
int primarrayspeicherung (int *primarray,int *bis)
{
int x,y,counter,e,valcounter=0,xcounter=0,xvalcounter=0,xx,xy,xe;
for(x=2;x<*bis;x++)
{
counter=0;
for(y=2;y<x;y++)
{
e=x%y;
if(e==0)
{
counter++;
}
}
if(counter==0)
{
valcounter++;
}
}
//ZWEITER DURCHGANG
primarray=new int[valcounter];
for(xx=2;xx<*bis;xx++)
{
xcounter=0;
for(xy=2;xy<xx;xy++)
{
xe=xx%xy;
if(xe==0)
{
xcounter++;
}
}
if(xcounter==0)
{
primarray[xvalcounter]=xx;
xvalcounter++;
}
}
return valcounter;
}
Best regards
In this function:
int primarrayspeicherung (int *primarray,int *bis)
primarray is a local variable. Everything you're doing to it (e.g. allocating, assigning) only affects the local primarray, not the one you pass in. If you want to modify both, you need to pass in a reference:
int primarrayspeicherung (int*& primarray,int *bis)

C++ Copy one struct value to other

I have a simple structure:
struct Appartament
{
char address[50];
char telephoneNumber[20];
char view[10];
double price;
double distanceFromCenter;
int roomCount;
};
I have some records written in a file. Now, I want to read all records from the file and to get only this who have roomCount smaller then a number (user input). This is easy, but the records should be displayed sorted by price. That's way I have to put them in a array and after that to sort them.
I have some problems and I believe that they are because I am not copping the structures well.
I have try different ways:
strcpy(CurrentRecords[index].address,currentRecord.address);
strcpy(CurrentRecords[index].telephoneNumber,currentRecord.telephoneNumber);
strcpy(CurrentRecords[index].view,currentRecord.view);
CurrentRecords[index].price=currentRecord.price;
CurrentRecords[index].distanceFromCenter=currentRecord.distanceFromCenter;
CurrentRecords[index].roomCount=currentRecord.roomCount;
or
memcpy(CurrentRecords[index],currentRecord,sizeof(Appartament));
and
CurrentRecords[index]=currentRecord
but nothing works...
EDIT: Here is the my code - "nothing works" refers to something like endless loop.
void AdvanceSearch()
{
clrscr();
Appartament currentRecord;
fstream currentFile("Records.dat",ios::binary|ios::in);
if(!currentFile)
{
cout<<"Error - the file could not be opened."<<endl;
return;
}
else
{
//Array with apartments records
Appartament CurrentRecords[MaxRecords];
currentFile.seekg(0L,ios::end);
long int length=currentFile.tellg();
currentFile.seekg(0L,ios::beg);
int isAppartamentFound=0;
if(length==0)
{
cout<<"The file is empty."<<endl;
return;
}
else
{
int userRoomCount;
do
{
clrscr();
cout<<"Enter apartment room count - ";
cin>>userRoomCount;
}while(userRoomCount<0);
clrscr();
cout<<endl<<"Apartments with "<<userRoomCount<<" rooms order by price:";
currentFile.read((char*)(&currentRecord),sizeof(Appartament));
int index=0;
while(!currentFile.eof())
{
if(currentRecord.roomCount==userRoomCount)
{
/*
strcpy(CurrentRecords[index].address,currentRecord.address);
strcpy(CurrentRecords[index].telephoneNumber,currentRecord.telephoneNumber);
strcpy(CurrentRecords[index].view,currentRecord.view);
CurrentRecords[index].price=currentRecord.price;
CurrentRecords[index].distanceFromCenter=currentRecord.distanceFromCenter;
CurrentRecords[index].roomCount=currentRecord.roomCount;
*/
memcpy(CurrentRecords[index],currentRecord,sizeof(Appartament));
//CurrentRecords[index]=currentRecord;
index++;
isAppartamentFound=1;
}
currentFile.read((char*)(&currentRecord),sizeof(Appartament));
}
currentFile.close();
}
if(isAppartamentFound==0)
{
cout<<endl<<"There are no matches!"<<endl;
}
else
{
//If only one apartment is found
if(sizeof(CurrentRecords)/sizeof(Appartament)==1)
{
cout<<endl;
ShowRecord(currentRecord);
}
else
{
//Sort the records
Appartament tempApartament;
int isChangeMade=1;
while(isChangeMade==1)
{
isChangeMade=0;
for(int index=0;index<(sizeof(CurrentRecords)/sizeof(Appartament))-1.0;index++)
{
if(CurrentRecords[index].price>CurrentRecords[index+1].price)
{
isChangeMade=1;
CopyApartament(tempApartament,CurrentRecords[index]);
CopyApartament(CurrentRecords[index],CurrentRecords[index+1]);
CopyApartament(CurrentRecords[index+1],tempApartament);
}
}
}
for(int index=0;index<sizeof(CurrentRecords)/sizeof(Appartament)-1.0;index++)
{
ShowRecord(CurrentRecords[index]);
}
}
}
}
}
void CopyApartament(Appartament RecordOne,Appartament RecordTwo)
{
/*
strcpy(RecordOne.address,RecordTwo.address);
RecordOne.distanceFromCenter=RecordTwo.distanceFromCenter;
RecordOne.price=RecordTwo.price;
RecordOne.roomCount=RecordTwo.roomCount;
strcpy(RecordOne.telephoneNumber,RecordTwo.telephoneNumber);
strcpy(RecordOne.view,RecordTwo.view);
*/
RecordOne=RecordTwo;
}
Note: I thought that my problem is the copying because I have not know how to do this.
CurrentRecords[index]=currentRecord;
That copies an entire structure and should work as expected.
Are you sure you are sorting correctly?
I don't see any particularly good reason to have explicit copying of the data anywhere. I think I'd do something like this:
std::vector<Apartment> get_apts(int max_rooms) {
std::vector<Apartment> apts;
std::copy_if(file.begin(), file.end(), std::back_inserter(apts),
[max_rooms](Apartment const &a) {
return a.roomCount < max_rooms;
});
std::sort(apts.begin(), apts.end(),
[](Apartment const &a, Apartment const &b) {
return a.price < b.price);
});
return apts;
}