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?
evinkeating 0 Newbie Poster
Aranarth 126 Posting Whiz in Training
Yes, there's an error in your code.
evinkeating 0 Newbie Poster
If so, why wouldn't it come up on windows?
Aranarth 126 Posting Whiz in Training
Because undefined behaviour can result in pretty much any behaviour, especially if it involves invalid pointer accesses.
kings_mitra -1 Junior Poster
Can you post the output for the program you get at linux command line...
evinkeating 0 Newbie Poster
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$
kings_mitra -1 Junior Poster
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.
evinkeating 0 Newbie Poster
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;
}
evinkeating 0 Newbie Poster
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.
Ancient Dragon 5,243 Achieved Level 70 Team Colleague Featured Poster
/* 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 <=
evinkeating 0 Newbie Poster
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.