cout crash problem

Hello, I'm not at all experienced in C++ so I need your help for this strange problem I have.
I have a small program that crashes all the time but at different places (same input). I guess it is some kind of memory issue like I'm not initializing some array's contents or I'm not reserving the memory I'm afterwards freeing or something like that, but I can't find anything wrong. I'm not posting all the code because it is more than 300 lines long but I will post a small fragment that crashes sometimes and I can not think of a single reason that might be the problem.

float k = solution[j*tasks+i];
cout << "p3.k" << endl;
cout << "p3." << k << endl;

on screen I get

p3.k
p3.


then it freezes for less than a second and then Windows 7 tells me that the program has stopped working.

I don't get how can it crash at a line that is printing a simple float variable.
Any ideas?

Right now the program crashes either in this line or at the end when it is finished and I'm just doing delete[] solution; which is memory I reserve with a new float[size].
You haven't provided enough code for anyone to assess what you've done.
float k = solution[j*tasks+i]; might have gone out of range and overwrote some random memory that std::cout was using, causing it to crash when it got to printing k.
OK, I will post the whole code but it is not beautiful..
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
#include <cstdlib>
#include <iostream>
#include <fstream>
using namespace std;
float * costs;							//matrix of costs
float * solution;						//solution matrix
int tasks;								//number of workers and jobs

int Initialize();
void Step1();
void Step2();
bool Step3();
bool OptimalAsignment(int coveredTasks, int worker, int * asignedTasks);
void Step2a();
int Uncross(int * crossedRow, int * crossedCol, int n, bool uncheckRow);
void Copy(int * source, int * destiny, int size);
void PrintSolution();
float CalculateCost();

int main(int argc, char *argv[])
{
 	if(Initialize() == 1)
	 	return 1;
	Step1();
	Step2();
	while(!Step3())
	{
		Step2a();
	}
	PrintSolution();
 	delete [] costs;
 	delete [] solution; 	 	 	//<<---- IT ALWAYS FAILS HERE IF IT GETS TO HERE
	return EXIT_SUCCESS;
}

int Initialize()
{
	fstream in_file;
 	in_file.open("Input.txt",iostream::in);
 	if (in_file.fail())
	{
		cout << "Failed in opening 'Input.txt' file" << endl;
 	 	return 1;
 	}
	in_file >> tasks;
	costs = new float[tasks*tasks];
	solution = new float[tasks*tasks];
	for (int i = 0; i < tasks*tasks; i++)
	{
		in_file >> costs[i];
		solution[i] = costs[i];
	}
 	in_file.close();
}

void Step1()
{
	float * rowMins = new float[tasks];
	for(int i = 0; i < tasks; i++)
		for(int j = 0; j < tasks; j++)
			if(j == 0 || rowMins[i] > solution[i*tasks+j])
				rowMins[i] = solution[i*tasks+j];
	for(int i = 0; i < tasks; i++)
		for(int j = 0; j < tasks; j++)
			solution[i*tasks+j] -= rowMins[i];
	delete[] rowMins;
}

void Step2()
{
	float * colMins = new float[tasks];
	for(int i = 0; i < tasks; i++)
		for(int j = 0; j < tasks; j++)
			if(i == 0 || colMins[j] > solution[i*tasks+j])
				colMins[j] = solution[i*tasks+j];
	for(int i = 0; i < tasks; i++)
		for(int j = 0; j < tasks; j++)
			solution[i*tasks+j] -= colMins[j];
	delete[] colMins;
}

bool Step3()
{
	bool result;
	int * asignedTasks = new int[tasks];
	for (int i = 0; i < tasks; i++)
		asignedTasks[i] = -1;
	result = OptimalAsignment(0, 0, asignedTasks);
	for (int i = 0; i < tasks; i++)
		solution[asignedTasks[i]*tasks+i] = -1;
	delete[] asignedTasks;
	return result;
}

bool OptimalAsignment(int coveredTasks, int worker, int * asignedTasks)
{
	if(coveredTasks == tasks)
		return true;
	int task = 0;
	while (task < tasks)
	{
		if(solution[worker*tasks+task] == 0 && asignedTasks[task] == -1)
		{
			asignedTasks[task] = worker;
			if(OptimalAsignment(coveredTasks+1, worker+1, asignedTasks))
				return true;
			else
				asignedTasks[task] = -1;
		}
		task++;
	}
	return false;
}

void Step2a()
{
	int * crossedRow = new int[tasks];
	int * crossedCol = new int[tasks];
	int * num0scol = new int[tasks];
	int * num0srow = new int[tasks];
	//Count the number of 0s in each row and column
	for(int i = 0; i < tasks; i++)
	{
		num0srow[i] = 0;
		crossedRow[i] = 0;
		for(int j = 0; j < tasks; j++)
		{
			if(i == 0)
			{
				num0scol[j] = 0;
				crossedCol[j] = 0;
			}
			if(solution[i*tasks+j] == 0)
			{
				num0srow[i]++;
				num0scol[j]++;
			}
		}
	}
	//cross all the rows and columns with more than one 0
	for(int i = 0; i < tasks; i++)
	{
		if(num0srow[i] > 1)
			crossedRow[i] = 1;
		if(num0scol[i] > 1)
			crossedCol[i] = 1;
	}
	delete[] num0scol;
	delete[] num0srow;
	//uncross the highest number of rows and columns possible
	Uncross(crossedRow, crossedCol, 0, true);
	//look for the lowest uncrossed cost
	float minimum = 0;
	for(int i = 0; i < tasks; i++)
	{
		//skip the crossed rows
		if(crossedRow[i] == 1)
			continue;
		for(int j = 0; j < tasks; j++)
		{
			//skip the crossed columns
			if(crossedCol[j] == 1)
				continue;
			if(minimum == 0 || minimum > solution[i*tasks+j])
				minimum = solution[i*tasks+j];
		}
	}
	//substract the minimum from all uncrossed and add it to the double crossed
	for(int i = 0; i < tasks; i++)
	{
		for(int j = 0; j < tasks; j++)
		{
			if(crossedCol[j] == 1 && crossedRow[i] == 1)
				solution[i*tasks+j] += minimum;
			else if(crossedCol[j] != 1 && crossedRow[i] != 1)
				solution[i*tasks+j] -= minimum;
		}
	}
	delete[] crossedRow;
	delete[] crossedCol;
}

/**
 *	Recursive method that uncrosses as much rows and columns as possible.
 *	Returns the number of rows and columns uncrossed.
 *	Recieves the arrays of crossed rows and columns; n is the number of row
 *	and column explored (the array is a square NxN);
 *	uncheckRow indicates if the row is explored or if false it is the column.
 *	The order of iteration is row n, then column n, then row n+1, etc.
 */
int Uncross(int * crossedRow, int * crossedCol, int n, bool uncheckRow)
{
	//declaration of auxiliary variables
	int * crossedRowAux, * crossedColAux;
	int uncrossResult = 0, result;
	bool uncrossable;
	//the end condition; outside of the square no more rows/cols are uncrossed
	if(n == tasks)
		return 0;
	//if exploring the row and if the row is crossed check if it can be uncrossed
	if(uncheckRow && crossedRow[n] == 1)
	{
		uncrossable = true;
		//iterate over all the elements in the row
		for(int i = 0; i < tasks; i++)
		{
			//if there is a 0 in the row that is not in a crossed column the row must stay crossed
			if(solution[n*tasks+i] == 0 && crossedCol[i] != 1)
				uncrossable = false;
		}
		//if it is possible to uncross the row...
		if(uncrossable)
		{
			//create a copy of the crossed rows and columns and uncross the row
			crossedRowAux = new int[tasks];
			crossedColAux = new int[tasks];
			Copy(crossedRow, crossedRowAux, tasks);
			Copy(crossedCol, crossedColAux, tasks);
			crossedRowAux[n] = 0;
			//save the number of uncrossed rows and columns with this recursive call
			uncrossResult = 1 + Uncross(crossedRowAux, crossedColAux, n, false);
		}
		//save the number of uncrossed rows and columns without uncrossing the row
		result = Uncross(crossedRow, crossedCol, n, false);
		//if more columns and rows are uncrossed if uncrossing the row copy the results
		if(uncrossResult > result)
		{
			Copy(crossedRowAux, crossedRow, tasks);
			Copy(crossedColAux, crossedCol, tasks);
			result = uncrossResult;
		}
		if(uncrossable)
		{
			//free the memory of the copies
			delete[] crossedRowAux;
			delete[] crossedColAux;
		}
		//return the best result
		return result;
	}
	//if the column is crossed check if it can be uncrossed
	else if(!uncheckRow && crossedCol[n] == 1)
	{
		uncrossable = true;
		//iterate over all the elements in the column
		for(int i = 0; i < tasks; i++)
		{
			//if there is a 0 in the column that is not in a crossed row the column must stay crossed
			if(solution[i*tasks+n] == 0 && crossedRow[i] != 1)
				uncrossable = false;
		}
		//if it is possible to uncross the column...
		if(uncrossable)
		{
			//create a copy of the crossed rows and columns and uncross the column
			crossedRowAux = new int[tasks];
			crossedColAux = new int[tasks];
			Copy(crossedRow, crossedRowAux, tasks);
			Copy(crossedCol, crossedColAux, tasks);
			crossedColAux[n] = 0;
			//save the number of uncrossed rows and columns with this recursive call
			uncrossResult = 1 + Uncross(crossedRowAux, crossedColAux, n+1, true);
		}
		//save the number of uncrossed rows and columns without uncrossing the row
		result = Uncross(crossedRow, crossedCol, n+1, true);
		//if more columns and rows are uncrossed if uncrossing the row copy the results
		if(uncrossResult > result)
		{
			Copy(crossedRowAux, crossedRow, tasks);
			Copy(crossedColAux, crossedCol, tasks);
			result = uncrossResult;
		}
		if(uncrossable)
		{
			//free the memory of the copies
			delete[] crossedRowAux;
			delete[] crossedColAux;
		}
		//return the best result
		return result;
	}
	if(uncheckRow)
		return Uncross(crossedRow, crossedCol, n, false);
	else
		return Uncross(crossedRow, crossedCol, n+1, true);
}

void Copy(int * source, int * destiny, int size)
{
	for(int i = 0; i < size; i++)
		destiny[i] = source[i];
}

void PrintSolution()
{
	cout << endl << endl;
 	for(int j = 0; j < tasks; j++)
 	{
 		for(int i = 0; i < tasks; i++)
 		{
			cout << solution[j*tasks+i] << "\t"; 	//<<--- IT ALSO CRASHES HERE SOMETIMES
		}
		cout << endl;
	}
}
I've marked the spots where it crashes and I had to remove some of the comments and debug comments (like what I posted before) because the code was too big.
There is obviously some problem with the memory or initialization of 'solution' but I am unable to localize it and I don't understand how can a printing fail. I understand that accessing random memory can fail, but then in the code I posted in the first post it should fail in the first line and not in the third one.

The input file I am using for this has the following content:

5
3 8 2 10 3
8 7 2 9 7
6 4 2 7 5
8 4 2 3 5
9 10 6 9 10
can you paste your input file also?

Edit: Thanks.
Last edited on
solution[asignedTasks[i]*tasks+i] = -1;

asignedTasks[i], sometimes return -1. check this and see if you solve your problem.
Last edited on
Thanks a lot writetonsharma! Now it is working. Actually I wasn't supposed to do the for containing that line if result is false, which is when I get -1s in adignedTask.
for better programming you should always check the return values or assignments.
try to minimize pointers and memory allocations. A programmer can make such programs using pointers which noone can understand. memory allocations make programs slow which are not suited for production environments. if you want to allocate, allocate in the beginning and de-allocate at the end of the program.

you dont look to be a new programmer at all as you mentioned. :)
Topic archived. No new replies allowed.