Why stack flow before execute main() - c++

I wrote code to implement graph's ADT with adjacent matrix. Then I want to build a project and desperate code.
#include<iostream>
#include<iomanip>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<queue>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1e3+10;
class Graph{
private:
int vertex;
int side;
int is_vis[maxn];
int degree[maxn];
int Edges[maxn][maxn];
public:
Graph(){
vertex=0;
memset(Edges,0x3f,sizeof Edges);
memset(is_vis,0,sizeof is_vis);
memset(degree,0,sizeof degree);
}
void Clear(){
vertex=0;
memset(Edges,0x3f,sizeof Edges);
memset(is_vis,0,sizeof is_vis);
memset(degree,0,sizeof degree);
}
void Clear_Vis(){memset(is_vis,0,sizeof is_vis);}
void PreVisit(int v){cout<<v<<" ";}
void SetMark(int u,int vis){is_vis[u]=vis;}
void Set_vertex(int n){vertex=n;} //顶点数
int Get_vertex(){return vertex;}
int Get_side() {return side;} //边数
void Add_edge(int u,int v,int val){ //加边
if(Edges[u][v]==INF){
side++;
degree[u]++;degree[v]++;
}
Edges[u][v]=Edges[v][u]=val;
}
void Cancle_edge(int u,int v){ //删边
if(Edges[u][v]!=INF){
side--;
degree[u]--;degree[v]--;
}
Edges[u][v]=Edges[v][u]=INF;
}
bool Have_edge(int u,int v){ //判断边是否存在
return Edges[u][v]==INF?0:1;
}
int Get_degree(int u){ //返回顶点u的度数
return degree[u];
}
void The_edge_node(int u){ //与顶点u相邻的点
int flag=1;
for(int i=0;i<vertex;i++){
if(i!=u&&Edges[u][i]!=INF){
cout<<i<<" ";flag=0;
}
}
if(flag)cout<<"No node next to "<<u<<".";
cout<<endl;
}
void DFS(int u){ //深度优先遍历
if(is_vis[u])return;
PreVisit(u);
SetMark(u,1);
for(int i=0;i<vertex;i++){
if(i==u||Edges[u][i]==INF||is_vis[i])continue;
DFS(i);
}
}
void BFS(int u){ //宽度优先遍历
memset(is_vis,0,sizeof is_vis);
queue<int>Q;
Q.push(u);
is_vis[u]=1;
while(!Q.empty()){
int out=Q.front();Q.pop();
cout<<out<<" ";
for(int i=0;i<vertex;i++){
if(i==out||Edges[out][i]==INF||is_vis[i])continue;
is_vis[i]=1;
Q.push(i);
}
}
}
void prt_Gra(){ //打印邻接矩阵
cout<<" ";
for(int i=0;i<vertex;i++){
cout<<" "<<left<<setw(3)<<i;
}
cout<<endl;
for(int i=0;i<vertex;i++){
cout<<" ";
for(int j=0;j<vertex*4;j++)cout<<"-";cout<<"-"<<endl;
cout<<left<<setw(2)<<i;
for(int j=0;j<vertex;j++){
cout<<"|";
if(i==j)cout<<left<<setw(3)<<0;
else if(Edges[i][j]==INF)cout<<left<<setw(3)<<'-';
else cout<<left<<setw(3)<<Edges[i][j];
}
cout<<"|"<<endl;
}
cout<<" ";
for(int j=0;j<vertex*4;j++)cout<<"-";cout<<"-"<<endl;
}
}My_graph;
void Get_menus(){
cout<<"1.新建一个图。"<<endl;
cout<<"2.增加一条边。"<<endl;
cout<<"3.删除一条边。"<<endl;
cout<<"4.判断边是否存在。"<<endl;
cout<<"5.查询顶点的度数。"<<endl;
cout<<"6.输出图的邻接矩阵。"<<endl;
cout<<"7.查询与顶点相邻的点。"<<endl;
cout<<"8.对图进行深度优先遍历。"<<endl;
cout<<"9.对图进行宽度优先遍历。"<<endl;
}
int main(){
My_graph.Clear();
int cmd,n,m,u,from,to,dist;
Get_menus();
while(1){
cout<<"请输入对应操作的序号:";cin>>cmd;cout<<endl;
if(cmd==1){
My_graph.Clear();
cout<<"请输入图的顶点数:";cin>>n;
My_graph.Set_vertex(n);cout<<endl;
cout<<"请输入图的边数:";cin>>m;cout<<endl;
cout<<"请依次输入各边的端点与长度:"<<endl;
for(int i=0;i<m;i++){
cin>>from>>to>>dist;
My_graph.Add_edge(from,to,dist);
}
cout<<"图的初始化完成!"<<endl;
}
if(cmd==2){
cout<<"请输入新增边的端点与长度:"<<endl;
cin>>from>>to>>dist;
My_graph.Add_edge(from,to,dist);
cout<<"加边完成!"<<endl;
}
if(cmd==3){
cout<<"请输入边的两个端点:";
cin>>from>>to;
My_graph.Cancle_edge(from,to);
cout<<"删边完成!"<<endl;
}
if(cmd==4){
cout<<"请输入边的两个端点:";
cin>>from>>to;
if(My_graph.Have_edge(from,to))cout<<"该边存在!"<<endl;
else cout<<"该边不存在!"<<endl;
}
if(cmd==5){
cout<<"请输入需要查询度数的顶点:";
cin>>u;cout<<endl;
cout<<"顶点"<<u<<"的度数为:"<<My_graph.Get_degree(u)<<endl;
}
if(cmd==6){
cout<<"图的邻接矩阵为:"<<endl;
My_graph.prt_Gra();
}
if(cmd==7){
cout<<"请输入需要查询相邻点的顶点:";
cin>>u;cout<<endl;
cout<<"与顶点"<<u<<"相邻的点有:"<<endl;
My_graph.The_edge_node(u);
}
if(cmd==8){
My_graph.Clear_Vis();
cout<<"请输入起点:";
cin>>u;cout<<endl;
cout<<"深度优先遍历的结果为:"<<endl;
My_graph.DFS(u);cout<<endl;
}
if(cmd==9){
cout<<"请输入起点:";
cin>>u;cout<<endl;
cout<<"宽度优先遍历的结果为:"<<endl;
My_graph.BFS(u);cout<<endl;
}
}
return 0;
}
/*
6 9
0 1 10
0 3 20
0 5 3
1 2 3
1 3 5
3 4 11
2 4 15
3 5 10
4 5 3
*/
But when I run the code, CodeBlocks says ''multiple definition of My_graph'.
Then I choose to define Graph's object in main() instead of in Graph.h. But this time the exe will exit before execute main().
Process returned -1073741571 (0xC00000FD)
This is main()code
I want to figure out what happened in constructor.

Even if you are not allocating your data on the stack, you won't be able to execute your code. This is the amount of data you want to allocate:
const int maxn=1e3+10;
int is_vis[maxn];
int degree[maxn];
int Edges[maxn][maxn];
I don't think your computer has enough space.
Use vectors, and resize the edges matrix ont he fly (do you need a matrix anyway? Probably not)
std::vector<int> is_vis;
std::vector<int> degree;
std::vector<std::vector<int>> Edges; // Change this to something sensible, perhaps a list of connections?

This is only for one error message "multiple definition...". For the other error see #MatthieuBrucher answer.
class Graph{
....
} My_graph;
This declares an instance global object of type Graph called My_graph.
Once you have this instance you can not declare it again:
Graph My_graph; //ERROR
This re-declaration may come not only in some function ('main' is a function) , but also from including the same .h header several times without include-guards.

Related

Code Blocks gives me following error upon execution of code(even parity hamming code)

error message
This is what it shows in the build log:
Checking for existence: C:\CodeBlocks\hammingcodeven.exe
Executing: '"C:\CodeBlocks/cb_console_runner.exe" "C:\CodeBlocks\hammingcodeven.exe"' (in 'C:\CodeBlocks')
Set variable: PATH=C:\MinGW\bin;C:\MinGW;C:\Windows\System32;C:\Windows;C:\Windows\System32\wbem;C:\Windows\System32\WindowsPowerShell\v1.0;C:\Windows\System32\OpenSSH;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Users\mahek\AppData\Local\Microsoft\WindowsApps
Process terminated with status -1073741510 (0 minute(s), 54 second(s))
This is the code to find binary value of m bit code after using an even parity hamming code
#include<iostream>
#include<math.h>
using namespace std;
class data
{
int A[50],m,r,ps[6],B[6][56],final[56];
public:
void show();
void input();
void findr();
void findps();
void binary();
void findfinal();
};
void data::input()
{
cout<<"Enter length of frame:";
cin>>m;
cout<<"Enter frame:";
for(int i=1;i<=m;i++)
{
cin>>A[i];
}
findr();
}
void data::findr()
{
r=0;
for(int i=1;i<=m;i++)
{
int x=pow(2,i);
if(x>(m+i+1))
{
r=i;
break;
}
}
if(r==0)
cout<<"Error";
binary();
}
void data::binary()
{
for(int i=1;i<=m+r;i++)
{
int h=i;
for(int j=r;j>=1;j--)
{
B[i][j]=h%2;
h=h/2;
}
}
findps();
}
void data::findps()
{
for(int i=1;i<=r;i++)
ps[i]=0;
for(int i=1;i<=m+r;i++)
{
for(int j=1;j<=r;j++)
{
ps[j]=ps[j]^B[i][j];
}
}
findfinal();
}
void data::findfinal()
{
for(int i=1,j=1;i<=m+r,j<=r;i++,j*=2)
{
if(i==j)
{
final[i]=ps[j];
}
else
final[i]=A[i];
}
}
void data::show()
{
cout<<"Input:";
for(int i=1;i<=m;i++)
cout<<A[i]<<" ";
cout<<endl;
cout<<"Output:";
for(int i=1;i<=m+r;i++)
cout<<final[i]<<" ";
}
int main()
{
data obj;
obj.input();
obj.show();
}
In the first loop of the function binary(), the variable i can go as high as m + r. In your example, m is 8, so m + r is at least 9. However, i is used to index the first dimension of B, which has a sizr of six. Accessing B outside of its defined size results in reading/writing other memory on the stack, resulting in undefined behavior. To help with this, you could dynamically allocate your fields with the needed size. I also strongly recommend giving your fields meaningful names to help people understand what your code is trying to do.
Furthermore, you are indexing arrays incorrectly. In C++ and many other languages, arrays are zero indexed, meaning that the first value of an array A of size n is at A[0] and the last value is at A[n-1].

How to solve 8-puzzle problem using Breadth-First search in C++

I want to build a c++ program that would solve 8-puzzle problem using BFS.
I want to show every generated state.
But the problem is, I don't know how to generate state.
I just want some clean function which will efficiently generate states and there will be a Explored array which will assure that there is no redundant state.
I've explored GitHub but there is too much complex solutions
I've written the following code till now
#include<iostream>
#include<conio.h>
using namespace std;
class puzzle{
private:
int initial[3][3],goal[3][3] = {{1,2,3},{4,5,6},{7,8,0}};
int queue[1000];
string data;
public:
void genratePuzzle();
void showState();
bool check_goal(int initial);
};
void puzzle::genratePuzzle(){
cout<<"\n***Create initial state 0-8***\n";
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
cout<<"Insert at ["<<i<<"]["<<j<<"] : ";
cin>>initial[i][j];
}
}
}
void puzzle::showState(){
cout<<"\n***State***\n";
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
cout<<initial[i][j]<<" ";
}
cout<<endl;
}
}
bool puzzle::check_goal(int initial){
bool check = true;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(initial[i][j] != goal[i][j]){
check = false;
}
}
}
return check;
}
int main(){
puzzle p1;
p1.genratePuzzle();
p1.showState();
getch();
}
Goal state
1 2 3
4 5 6
7 8 0
Put your state into
struct state {
int data[3][3];
bool operator < (const state & other) {
for (int y=0; y<3; ++y) {
for (int x=0; x<3; ++x) {
if (data[y][x] < other.data[y][x]) {
return true;
}
if (data[y][x] > other.data[y][x]) {
return false;
}
}
}
return false; // all were equal
}
}
Now you can use values of type state as keys in a std::map e.g. make a std::map<state, bool> explored if you want. It behaves like an array indexed by states, so:
state a;
// do something to the state...
// and you can do this
explored[a] = true;
How do you generate new states? You start with an existing state and try all valid moves on it. Repeat until done.

Why did this TSP code fail in the case mentioned but worked else where?

I am implementing Travelling Salesman Problem with Dynamic approach. I have added my attempt below. The code compiled and gave correct output for most of the cases. However, it failed when I had matrix representation: [[0,10,1],[1,0,10],[10,1,0]]. I expect the result to be 3 but it is showing me 30 as the output.
I have done recursion calls and dict map stores the keys for memorization.
#include<bits/stdc++.h>
using namespace std;
int v;
int G[10][10];
int parent[10];
map<pair<int,set<int> >, int > dict;
void solve(int,set<int>);
int tsp(int,set<int>);
int main(){
set<int> s,s_o;
set<int>::iterator it;
cout<<"Give number of vertices"<<endl;
cin>>v;
for(int i=0;i<v;i++)
s.insert(i);
//cout<<"Give number of edges"<<endl;
//cin>>e;
s_o=s;
cout<<"Give edges"<<endl;
for(int i=0;i<v;i++){
for(int j=0;j<v;j++){
cin>>G[i][j];
}
}
solve(0,s);
return 0;
}
void solve(int i,set<int> s){
parent[i]=-1;
set<int>::iterator it;
it=s.find(i);
s.erase(it);
// for(it=s.begin();it!=s.end();++it)
// cout<<*it<<" ";
int ans=tsp(0,s);
cout<<ans<<endl;
for(int i=0;i<v;i++)
cout<<parent[i]<<" ";
cout<<endl;
}
int tsp(int a,set<int>s){
set<int>::iterator it;
int min_cost=1000000;
int k,min_k;
if(s.empty()){
return G[a][0];
}
for(it=s.begin();it!=s.end();++it){
k=*it;
s.erase(it);
if(dict.find(pair<int, set<int> >(k,s))!=dict.end()){
//cout<<"here"<<endl;
return G[a][k]+ dict.at(pair<int, set<int> >(k,s));
}
else{
if(tsp(k,s)<min_cost){
min_cost=tsp(k,s);
min_k=k;
}
pair<int,set<int> > x(k,s);
dict.insert(pair<pair<int, set<int> >,int >(x,min_cost));
parent[a]=min_k; //i must admit that this is accidental, but
//it worked xD
return G[a][k]+min_cost;
}
}
}
Also the parent array I expect to hold parent of vertex and -1 for source(0 in case).
Is there anything wrong in the tsp() function? If not, why did it give answer as 30?
Also, what is wrong in the parent array use?
Thank you for your help! :)

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.

Newbie - matrix addition implementation in c++

Hello i'm trying to program the addition of 2 matrices into a new one (and it does when i run the program step by step) but for some reason VS 2010 gives me an access error after it does the addition.
Here is the code.
#include <iostream>
#include <cstdio>
#include <conio>
using namespace std;
class operatii
{
typedef double mat[5][5];
mat ms,m1,m2;
int x1,x2,y1,y2;
public:
void preg();
int cit_val();
void cit_mat(int&,int&,double[5][5]);
void suma();
void afisare(int&,int&,double[5][5]);
};
void operatii::preg()
{
cit_mat(x1,y1,m1);
cit_mat(x2,y2,m2);
suma();
afisare(x1,y1,ms);
}
int operatii::cit_val()
{
int n;
cin>>n;
return n;
}
void operatii::cit_mat(int& x,int& y,double m[5][5])
{
char r;
cout<<"Matrice patratica? Y/N ";
cin>>r;
if ((r=='y')||(r=='Y'))
{
cout<<"Numar linii si coloane: ";
x=cit_val();
y=x;
}
else
{
cout<<"Numar linii: ";
x=cit_val();
cout<<"Numar coloane: ";
y=cit_val();
}
for (int i=1;i<=x;i++)
for (int j=1;j<=y;j++)
cin>>m[i][j];
}
void operatii::suma()
{
if ((x1==x2)&&(y1==y2))
for (int i=1;i<=x1;i++)
for (int j=1;i<=y1;j++)
ms[i][j]=m1[i][j]+m2[i][j];
else cout<<"Eroare";
}
void operatii::afisare(int& x,int& y,double m[5][5])
{
cout<<endl;
for (int i=1;i<=x;i++)
{
for (int j=1;j<=y;j++)
cout<<m[i][j];
cout<<endl;
}
}
void main()
{
operatii matrice;
matrice.preg();
system("PAUSE");
}
Any kind of help would be apreciated.
Arrays are 0-based in c++.
Change your various variants of for (somevar=1; somevar<=something) to for (somevar=0; somevar<something)
You're writing past the end of your arrays, which overwrites stack return address, leading to a return to nonexecutable code, again leading to an access violation.
Also,
for (int j=1;i<=y1;j++)
I think you want to use j not i here. Such errors are much easier to see if you use longer and more distinct variable names than "i" and "j", such as e.g. "Line" and "Column"