I have a program that works fine under windows, but when i run it on Unix I get a very slightly diffent set of results, followed by a 'segmentation fault' message. I'm at a loss to explain why. Any ideas?

Recommended Answers

All 10 Replies

Yes, there's an error in your code.

If so, why wouldn't it come up on windows?

Because undefined behaviour can result in pretty much any behaviour, especially if it involves invalid pointer accesses.

Can you post the output for the program you get at linux command line...

Here's the expected output (from Windows)

x[0] = -0.170899
x[1] = -24.825800
x[2] = -5.366003
x[3] = -14.666984
x[4] = -18.148497
x[5] = -5.492753
x[6] = 33.347752
x[7] = 10.707899
x[8] = -15.025283
x[9] = 9.211628
x[10] = 2.434786
x[11] = 22.375307
x[12] = -1.287022
x[13] = 17.096430
x[14] = 16.252802
x[15] = -1.898077
x[16] = 5.200597
x[17] = 14.853777
x[18] = 27.115179
x[19] = -14.855241
x[20] = 27.204290
x[21] = 1.783676
x[22] = 0.850488
x[23] = 1.152569
x[24] = 24.032516
x[25] = -20.864252
x[26] = -12.747918
x[27] = 14.815158
x[28] = 9.386512
x[29] = 0.316148
x[30] = 0.225964
x[31] = 13.016247
x[32] = 6.822095
x[33] = -17.158594
x[34] = -8.890490
x[35] = -6.730474
x[36] = 7.815812
x[37] = 29.211090
x[38] = 8.633213
x[39] = -9.243457
x[40] = -6.701235
x[41] = 1.967517
x[42] = -30.733067
x[43] = 19.107956
x[44] = 21.391073
x[45] = 1.608435
x[46] = 22.420971
x[47] = -4.515589
x[48] = -8.783605
x[49] = 2.446114
x[50] = 13.176244
x[51] = 26.302586
x[52] = 5.328269
x[53] = 4.063350
x[54] = 12.171098
x[55] = -4.651814
x[56] = -39.664776
x[57] = -17.818052
x[58] = 6.483833
x[59] = -3.897195
x[60] = 24.516638
x[61] = -23.337313
x[62] = -5.739232
x[63] = -26.434000
x[64] = -10.644997
x[65] = -8.022816
x[66] = -29.939722
x[67] = -40.479568
x[68] = 11.557791
x[69] = 19.102407
x[70] = 11.454553
x[71] = 12.017144
x[72] = -3.413656
x[73] = -23.695114
x[74] = 39.615559
x[75] = -8.594134
x[76] = 16.151867
x[77] = 8.607333
x[78] = -3.846002
x[79] = -8.367295
x[80] = -11.316942
x[81] = -6.185081
x[82] = 10.226036
x[83] = -15.605256
x[84] = 6.683823
x[85] = 20.086893
x[86] = 15.102418
x[87] = 10.515800
x[88] = 17.950630
x[89] = -18.956255
x[90] = -2.916969
x[91] = -16.738712
x[92] = -20.680040
x[93] = -20.960184
x[94] = -1.127950
x[95] = 8.332426
x[96] = -3.881704
x[97] = -3.016245
x[98] = -23.640543
x[99] = 1.370455
Time elapsed: 0.156000
Press any key to continue . . .

And the unix output:
x[0] = -0.171061
x[1] = -24.809633
x[2] = -5.362887
x[3] = -14.659243
x[4] = -18.136869
x[5] = -5.489952
x[6] = 33.327526
x[7] = 10.700518
x[8] = -15.015988
x[9] = 9.205112
x[10] = 2.434088
x[11] = 22.360220
x[12] = -1.286863
x[13] = 17.086384
x[14] = 16.242186
x[15] = -1.897454
x[16] = 5.197708
x[17] = 14.843376
x[18] = 27.098156
x[19] = -14.844092
x[20] = 27.187263
x[21] = 1.783594
x[22] = 0.848973
x[23] = 1.152206
x[24] = 24.018721
x[25] = -20.850784
x[26] = -12.739766
x[27] = 14.807188
x[28] = 9.379039
x[29] = 0.315925
x[30] = 0.225662
x[31] = 13.006242
x[32] = 6.816948
x[33] = -17.145935
x[34] = -8.883874
x[35] = -6.726199
x[36] = 7.808394
x[37] = 29.191271
x[38] = 8.627698
x[39] = -9.237696
x[40] = -6.695858
x[41] = 1.967010
x[42] = -30.711441
x[43] = 19.096853
x[44] = 21.379240
x[45] = 1.607849
x[46] = 22.405445
x[47] = -4.511552
x[48] = -8.777048
x[49] = 2.446999
x[50] = 13.167504
x[51] = 26.286160
x[52] = 5.324668
x[53] = 4.060307
x[54] = 12.162321
x[55] = -4.647701
x[56] = -39.640148
x[57] = -17.806747
x[58] = 6.479012
x[59] = -3.894578
x[60] = 24.500515
x[61] = -23.321236
x[62] = -5.733843
x[63] = -26.417152
x[64] = -10.638539
x[65] = -8.017982
x[66] = -29.920588
x[67] = -40.452866
x[68] = 11.550165
x[69] = 19.089745
x[70] = 11.446381
x[71] = 12.009503
x[72] = -3.413560
x[73] = -23.680004
x[74] = 39.591930
x[75] = -8.589814
x[76] = 16.142508
x[77] = 8.601611
x[78] = -3.843857
x[79] = -8.361790
x[80] = -11.310701
x[81] = -6.180703
x[82] = 10.219684
x[83] = -15.593319
x[84] = 6.680372
x[85] = 20.073750
x[86] = 15.093052
x[87] = 10.507348
x[88] = 17.940199
x[89] = -18.944376
x[90] = -2.916000
x[91] = -16.727081
x[92] = -20.667299
x[93] = -20.946669
x[94] = -1.127366
x[95] = 8.326338
x[96] = -3.879202
x[97] = -3.014213
x[98] = -23.625191
x[99] = 1.368482
Segmentation fault
ekeating@csicluster:~/project$

I doubt whether its the same code in both the cases, as you are performing some illegal memory access for getting the elapsed time.
Ok, post you code that you are using in Linux.

This probably won't make sense unless you understand the input file format and Cholesky factorisation, but you did ask!

/* Sequential Matrix Cholesky Factorisation Program */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

int main()
{
	clock_t start = clock();

	int dimention, num_elements;
	int *xadj, *adj;
	float *values;
	float **lower_tri;
	float *b_vector, *x_vector, *y_vector;
	int i =0, j =0, k =0;

	/* Read matrix info from file */
	FILE *file_pointer;
	file_pointer = fopen("test.mat", "rb");
	if (file_pointer == NULL) {fputs ("File error",stderr); exit (1);}

	fscanf(file_pointer, "%d", &dimention);
	fscanf(file_pointer, "%d", &num_elements);

	/* declare arrays to store info */
	xadj = (int*)malloc(sizeof(int)*(dimention+1));
	adj = (int*)malloc(sizeof(int)*num_elements);
	values = (float*)malloc(sizeof(float)*num_elements);
	
	/* populate arrays with file info */
	while(!feof(file_pointer)) {
		for(i =0; i < dimention+1; ++i)
			fscanf(file_pointer, "%d", &xadj[i]);
		for(i =0; i < num_elements; ++i)
			fscanf(file_pointer, "%d", &adj[i]);
		for(i =0; i < num_elements; ++i)
			fscanf(file_pointer, "%f", &values[i]);
	}
	fclose(file_pointer);

	/* dynamically declare array to store tiangular matrices */
	lower_tri = (float **)malloc(sizeof(float *)*(dimention));
	for(i =0; i < dimention; ++i)
		lower_tri[i] = (float *)malloc(sizeof(float)*(i+1));

	/* initialise triangular matrix to zero */
	for(i =0; i < dimention; ++i)
		for(j =0; j <= i+1; ++j)
			lower_tri[i][j] = 0;                                            

	/* calculate the rest of lower triangular matrix */
	for(j =0; j < dimention; ++j) {
		for(i =j; i < dimention; ++i) {
			/* find corresponding non zero value (if any) */
			for(k = xadj[j]; k < xadj[j+1]; ++k)
				if(adj[k] == i)
					lower_tri[i][j] = values[k];

			for(k = j-1; k >= 0; --k)
				lower_tri[i][j] -= lower_tri[i][k]*lower_tri[j][k];

			if(i == j)	/* diagonal term */
				lower_tri[i][j] = (float)sqrt(lower_tri[i][j]);
			else		/* off diagonal term */
				lower_tri[i][j] /= lower_tri[j][j];
		}
	}

	b_vector = (float*)malloc(sizeof(float)*dimention);
	
	/******************************** ENTER VALUES FOR B */
	for(i =0; i < dimention; ++i)
		b_vector[i] = 1;
	/*******************************************************/

	/* initialise x and y vectors */
	x_vector = (float*)malloc(sizeof(float)*dimention);
	y_vector = (float*)malloc(sizeof(float)*dimention);

	/* solve for vector y */
	for(i =0; i < dimention; ++i) {
		y_vector[i] = b_vector[i];
		for(j =0; j < i; ++j)
			y_vector[i] -= lower_tri[i][j]*y_vector[j];
		y_vector[i] /= lower_tri[i][i];
	}

	/* solve for vector x */
	for(i = dimention-1; i >= 0; --i) {
		x_vector[i] = y_vector[i];
		for(j = dimention-1; j > i; --j)
			/* instead of upper triangular matrix, 
			 switch i and j of lower triangular matrix
			 i.e. upper_tri[i][j] == lower_tri[j][i] */
			x_vector[i] -= lower_tri[j][i]*x_vector[j];
		x_vector[i] /= lower_tri[i][i];
	}

	for(i =0; i < dimention; ++i)
		printf("x[%d] = %f \n", i, x_vector[i]);

	free(xadj);
	free(adj);
	free(values);
	free(lower_tri);
	free(b_vector);
	free(x_vector);
	free(y_vector);

	printf("Time elapsed: %f\n", ((double)clock() - start) / CLOCKS_PER_SEC);

	return 0;
}

Right, I've narrowed it down to line 107. I can't free lower_tri like this, presumably because of the way I've declared the array.

As a last resort I can declare this as

/* dynamically declare array to store tiangular matrices */
lower_tri = (float **)malloc(sizeof(float *)*(dimention));
for(i =0; i < dimention; ++i)
	lower_tri[i] = (float *)malloc(sizeof(float)*(dimention));

instead of

/* dynamically declare array to store tiangular matrices */	
lower_tri = (float **)malloc(sizeof(float *)*(dimention));	
for(i =0; i < dimention; ++i)
	lower_tri[i] = (float *)malloc(sizeof(float)*(i+1));

But is there a way I can free the second memory allocation? I tried a for loop but just got more errors.

/* initialise triangular matrix to zero */	
for(i =0; i < dimention; ++i)		
   for(j =0; j <= i+1; ++j)			
    lower_tri[i][j] = 0;

The above causes buffer overrun. The inner loop should be < not <=

Thanks AD. You're right, works fine now. Don't know how I missed that. Or what I was thinking when I wrote it.

Sorry about the duplicate thread.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.