unpredictable deterministic behaviour again

A

a

After taking advice from previous replies, 1D and 2D arrays are allocated
by:


#define SIZE 12

smark = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
smark = calloc(SIZE,sizeof(struct tagged_array));
}
omark = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
omark = calloc(SIZE,sizeof(struct tagged_array));
}
sdist = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
sdist = calloc(SIZE,sizeof(struct tagged_array));
}
odist = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
odist = calloc(SIZE,sizeof(struct tagged_array));
}
assg_under_chair = calloc(SIZE,sizeof(int *));
for(i=0;i<SIZE;i++) {
assg_under_chair = calloc(SIZE,sizeof(int));
occ=0;
}



The values of the array are perfectly correct. But in the following loop,


for (k=0; k<SIZE; k++) { //for each chairman, id only, no
location implication
for (kk=0; kk<SIZE; kk++) { //moving to diff location
cost = 0;

for (j=0; j<SIZE; j++) { //objecting other chairmen in
other rows
for (jj=0; jj<SIZE; jj++) { //objecting other chairmen
in other rows
printf(" a: %d ", assg_under_chair[j][jj] ) ;
if ( assg_under_chair[j][jj] == k ) {
cost = cost + ( (odist[kk][jj].value) * (occ[k]) );
printf("3: %lf %lf %lf \n",cost ,
odist[kk][jj].value , occ[k] );
break;
}
}
}

}
}

the three %lf are all zeros. But once out of this loop, the values PRINTED
OUT immediately become normal again. Would anybody know what happens?
 
A

a

printf(" a: %d ", assg_under_chair[j][jj] ) ;
This printing is correct
if ( assg_under_chair[j][jj] == k ) {
cost = cost + ( (odist[kk][jj].value) * (occ[k]) );
printf("3: %lf %lf %lf \n",cost ,
odist[kk][jj].value , occ[k] );
break;
}
This is not just a print out problem because the result obtained here will
be used to find out the final answer. And the final answer shows that the
values stored in these 3 variables at this instance are really all zeros.

I doubt it is again incorrect access of memory makes them temporarily
behaviour strangely but just don't know what can happen in a
nested-4-for-loop.
 
J

James Kuyper

a said:
After taking advice from previous replies, 1D and 2D arrays are allocated
by:


#define SIZE 12

smark = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
smark = calloc(SIZE,sizeof(struct tagged_array));
}
omark = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
omark = calloc(SIZE,sizeof(struct tagged_array));
}
sdist = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
sdist = calloc(SIZE,sizeof(struct tagged_array));
}
odist = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
odist = calloc(SIZE,sizeof(struct tagged_array));
}
assg_under_chair = calloc(SIZE,sizeof(int *));
for(i=0;i<SIZE;i++) {
assg_under_chair = calloc(SIZE,sizeof(int));
occ=0;
}


Do you know whether or not any of the calloc() calls actually succeeded?
If so, how? If not, why not? Hint: you didn't check!

Declarations for the variables you've used would be helpful.
The values of the array are perfectly correct. But in the following loop,


for (k=0; k<SIZE; k++) { //for each chairman, id only, no
location implication
for (kk=0; kk<SIZE; kk++) { //moving to diff location
cost = 0;

for (j=0; j<SIZE; j++) { //objecting other chairmen in
other rows
for (jj=0; jj<SIZE; jj++) { //objecting other chairmen
in other rows
printf(" a: %d ", assg_under_chair[j][jj] ) ;
if ( assg_under_chair[j][jj] == k ) {
cost = cost + ( (odist[kk][jj].value) * (occ[k]) );
printf("3: %lf %lf %lf \n",cost ,
odist[kk][jj].value , occ[k] );

Do you know that all three of those variables are 'double'? You haven't
told us enough to figure out whether "%lf" is an appropriate format string.
break;
}
}
}

}
}

the three %lf are all zeros. But once out of this loop, the values PRINTED
OUT immediately become normal again. Would anybody know what happens?

Every call to calloc() creates a block of memory which, if accessed as
unsigned char, has every byte equal to zero. As a result, when you
access any part of that memory using an integer type, the value will be
0. In most implementations, if you access any part of that memory using
a floating point type, the value will be 0.0 (though portable code
should not rely on that fact - all floating point variables should be
initialized before first use, by some other means). The only code you've
shown us which sets the value of any object other than pointers and loop
variables is:

occ = 0;
cost = 0;
cost = cost + ( (odist[kk][jj].value) * (occ[k]) );

Under those circumstances, I don't see any reason why you should expect
cost, odist[kk][jj].value or occ[k] to have non-zero values. If you
think that they should be non-zero, you need to explain why. Actual code
would be helpful; code which has been simplified while still generating
unexpected results would be even better.

Note: as you've already found out, the process of simplifying a problem
enough to present it to this newsgroup will often lead you to the cause
of the problem before you've even sent it out.
 
A

a

Sorry if the codes posted here are thought be dumped because several years
ago i was warned to give only necessary codes.

data:
12

0 90 10 23 43 0 0 0 0 0 0 0
90 0 0 0 0 88 0 0 0 0 0 0
10 0 0 0 0 0 26 16 0 0 0 0
23 0 0 0 0 0 0 0 0 0 0 0
43 0 0 0 0 0 0 0 0 0 0 0
0 88 0 0 0 0 0 0 1 0 0 0
0 0 26 0 0 0 0 0 0 0 0 0
0 0 16 0 0 0 0 0 0 96 0 0
0 0 0 0 0 1 0 0 0 0 29 0
0 0 0 0 0 0 0 96 0 0 0 37
0 0 0 0 0 0 0 0 29 0 0 0
0 0 0 0 0 0 0 0 0 37 0 0

0 36 54 26 59 72 9 34 79 17 46 95
36 0 73 35 90 58 30 78 35 44 79 36
54 73 0 21 10 97 58 66 69 61 54 63
26 35 21 0 93 12 46 40 37 48 68 85
59 90 10 93 0 64 5 29 76 16 5 76
72 58 97 12 64 0 96 55 38 54 0 34
9 30 58 46 5 96 0 83 35 11 56 37
34 78 66 40 29 55 83 0 44 12 15 80
79 35 69 37 76 38 35 44 0 64 39 33
17 44 61 48 16 54 11 12 64 0 70 86
46 79 54 68 5 0 56 15 39 70 0 18
95 36 63 85 76 34 37 80 33 86 18 0



program:

common.h:

struct tagged_array {
int tag;
double value;
};


#define SIZE 12
#define JUDGE 5

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <limits.h>
#include <sys/param.h>

#include "common.h"

int main(int argc, char **argv) {

FILE *file; int i=0;

int *Massg; double *Mcost; //double *Msdist;

double winner=0x7FFFFF;
int winner_id=0;
int u=0;

char buf[SIZE*30]="";
struct tagged_array **smark;
struct tagged_array **omark;
struct tagged_array **sdist;
struct tagged_array **odist;
int chair_assg[JUDGE+1][SIZE];
int **assg_under_chair;
double *r;
double *util_1d;
double *score;
double occ[SIZE];
int firstline = 0;
int f = 0;

int t=0,k,kk,j,jj,cost,mid,did;

smark = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
smark = calloc(SIZE,sizeof(struct tagged_array));
}
omark = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
omark = calloc(SIZE,sizeof(struct tagged_array));
}
sdist = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
sdist = calloc(SIZE,sizeof(struct tagged_array));
}
odist = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
odist = calloc(SIZE,sizeof(struct tagged_array));
}
assg_under_chair = calloc(SIZE,sizeof(int *));
for(i=0;i<SIZE;i++) {
assg_under_chair = calloc(SIZE,sizeof(int));
occ=0;
}

score = malloc(SIZE * sizeof(double));
r = malloc(SIZE * SIZE * sizeof(double));
util_1d = malloc(SIZE * SIZE * sizeof(double));
Massg = malloc(SIZE * SIZE * sizeof(int));
Mcost = malloc(SIZE * SIZE * sizeof(double));
if (argc == 0) puts("usage: fn input");

file = fopen(argv[1], "r");

if(file==NULL) {
printf("Error: can't open file.\n");
return 1;
}
else {
printf("File opened successfully.\n");
i=0;
fscanf(file, "%lf", &k);//size
while(!feof(file) ) {

fscanf(file, "%lf", &r); //printf("i:%d r:%lf\n",i, r);
i++;
}
}

t=0;
//finish reading/generating omark chain matrix
for (k=0; k<SIZE; k++) {
for (kk=0; kk<SIZE; kk++) {
omark[k][kk].value = smark[k][kk].value = r[k*SIZE+kk];
odist[k][kk].value = sdist[k][kk].value = r[(k+SIZE)*SIZE+kk];
omark[k][kk].tag = smark[k][kk].tag = odist[k][kk].tag = sdist[k][kk].tag
= kk;
occ[k] += omark[k][kk].value;
}

score[k] = 0.0;
chair_assg[t][k] = k;
}

u = 0;
for (k=0; k<SIZE; k++) { //for each chairman, id only, no location
implication
for (kk=0; kk<SIZE; kk++) { //moving to diff location
cost = 0;

for (j=0; j<SIZE; j++) { //objecting other chairmen in other rows
for (jj=0; jj<SIZE; jj++) { //objecting other chairmen in other rows
printf(" a: %d ", assg_under_chair[j][jj] ) ;
if ( assg_under_chair[j][jj] == k ) {
cost = cost + ( (odist[kk][jj].value) * (occ[k]) );
printf("3: %lf %lf %lf \n",cost , odist[kk][jj].value , occ[k] );
break;
}
}
}

}
}
return 0;
}
 
J

James Kuyper

a said:
Sorry if the codes posted here are thought be dumped because several years
ago i was warned to give only necessary codes.

That's true, but you should give ALL of the necessary code. Which means
you need to simplify the code as much as possible before presenting it.

....
int t=0,k,kk,j,jj,cost,mid,did; ....
fscanf(file, "%lf", &k);//size

Key problem #1: k is an integer, so %lf is the wrong format. Change to %d.
....
printf("3: %lf %lf %lf \n",cost , odist[kk][jj].value , occ[k] );

Key problem #2: cost has type 'int', you can't use a "%lf". Use "%d"
instead. Alternatively, change 'cost' to be a double and continue using
"%lf". Whichever way you fix it, make sure that the format string
matches the promoted type of the corresponding argument.

With those fixes, I'm seeing lots of non-zero values printed out by the
second printf() call. I'm seeing a huge number of "a; 0 " sequences
printed out one right after another without any new lines between them.
However, I can't tell from the code whether or not that's what you
wanted it to do.

Notice that two of the three lines I needed to see in order to help you
were not in the code extract you originally gave us. In my experience,
whenever someone gives us only part of his code, it usually does not
include everything we need to figure out the problem.
 
B

Barry Schwarz

Sorry if the codes posted here are thought be dumped because several years
ago i was warned to give only necessary codes.

data:
12

0 90 10 23 43 0 0 0 0 0 0 0
90 0 0 0 0 88 0 0 0 0 0 0
10 0 0 0 0 0 26 16 0 0 0 0
23 0 0 0 0 0 0 0 0 0 0 0
43 0 0 0 0 0 0 0 0 0 0 0
0 88 0 0 0 0 0 0 1 0 0 0
0 0 26 0 0 0 0 0 0 0 0 0
0 0 16 0 0 0 0 0 0 96 0 0
0 0 0 0 0 1 0 0 0 0 29 0
0 0 0 0 0 0 0 96 0 0 0 37
0 0 0 0 0 0 0 0 29 0 0 0
0 0 0 0 0 0 0 0 0 37 0 0

0 36 54 26 59 72 9 34 79 17 46 95
36 0 73 35 90 58 30 78 35 44 79 36
54 73 0 21 10 97 58 66 69 61 54 63
26 35 21 0 93 12 46 40 37 48 68 85
59 90 10 93 0 64 5 29 76 16 5 76
72 58 97 12 64 0 96 55 38 54 0 34
9 30 58 46 5 96 0 83 35 11 56 37
34 78 66 40 29 55 83 0 44 12 15 80
79 35 69 37 76 38 35 44 0 64 39 33
17 44 61 48 16 54 11 12 64 0 70 86
46 79 54 68 5 0 56 15 39 70 0 18
95 36 63 85 76 34 37 80 33 86 18 0



program:

common.h:

struct tagged_array {
int tag;
double value;
};


#define SIZE 12
#define JUDGE 5

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <limits.h>
#include <sys/param.h>

#include "common.h"

int main(int argc, char **argv) {

FILE *file; int i=0;

int *Massg; double *Mcost; //double *Msdist;

double winner=0x7FFFFF;
int winner_id=0;
int u=0;

char buf[SIZE*30]="";
struct tagged_array **smark;
struct tagged_array **omark;
struct tagged_array **sdist;
struct tagged_array **odist;
int chair_assg[JUDGE+1][SIZE];
int **assg_under_chair;
double *r;
double *util_1d;
double *score;
double occ[SIZE];
int firstline = 0;
int f = 0;

int t=0,k,kk,j,jj,cost,mid,did;

smark = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
smark = calloc(SIZE,sizeof(struct tagged_array));
}
omark = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
omark = calloc(SIZE,sizeof(struct tagged_array));
}
sdist = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
sdist = calloc(SIZE,sizeof(struct tagged_array));
}


Please, please, please learn to indent consistently.
odist = calloc(SIZE,sizeof(struct tagged_array*));
for(i=0;i<SIZE;i++) {
odist = calloc(SIZE,sizeof(struct tagged_array));
}
assg_under_chair = calloc(SIZE,sizeof(int *));
for(i=0;i<SIZE;i++) {
assg_under_chair = calloc(SIZE,sizeof(int));
occ=0;
}

score = malloc(SIZE * sizeof(double));
r = malloc(SIZE * SIZE * sizeof(double));
util_1d = malloc(SIZE * SIZE * sizeof(double));
Massg = malloc(SIZE * SIZE * sizeof(int));
Mcost = malloc(SIZE * SIZE * sizeof(double));
if (argc == 0) puts("usage: fn input");


If argc is 0, you proceed on to the next step to use argv[1] even
though you know it doesn't exist.
file = fopen(argv[1], "r");

If argc is 1, argv[1] will be NULL and this invokes undefined
behavior.
if(file==NULL) {
printf("Error: can't open file.\n");
return 1;
}
else {
printf("File opened successfully.\n");
i=0;
fscanf(file, "%lf", &k);//size

&k is an int*. %lf expects a double*. This alone constitutes
undefined behavior. However, on most systems different types of
pointers have the same attributes so it may not have practical impact.
If k is not properly aligned for an double, this invokes "real"
undefined behavior. If sizeof(double) is greater than sizeof(int),
this will overflow beyond the end of k, also "real" undefined
behavior. In all probability, it will overlay some other part of your
program which you wish it wouldn't. In any event, the value stored in
k, if any, will not be what you expect for an int. This is at least
undesirable behavior.
while(!feof(file) ) {

feof will not return 1 until you have already tried to read past the
end of the file. If you have just read the last data, this will cause
you to attempt one additional read. No data will be stored in the
specified object but i will be incremented.
fscanf(file, "%lf", &r); //printf("i:%d r:%lf\n",i, r);


r is allocated enough space for 144 doubles. Your file contains at
least 288 values. You overflow the allocated space, definite
undefined behavior. And you never close the file.
i++;
}
}

t=0;
//finish reading/generating omark chain matrix
for (k=0; k<SIZE; k++) {
for (kk=0; kk<SIZE; kk++) {
omark[k][kk].value = smark[k][kk].value = r[k*SIZE+kk];

You obviously have no trouble allocating 2d arrays, e.g., omark. Why
did you choose to "simulate" a 2d array with r? And you do it wrong
in the next statement.
odist[k][kk].value = sdist[k][kk].value = r[(k+SIZE)*SIZE+kk];

For all k greater than 1 or kk greater than 0, the r index is out of
range. Valid indices for r range from 0 to 143. When k is3, this
index is at least 180. Who knows what memory you are accessing but it
is definitely undefined behavior.
omark[k][kk].tag = smark[k][kk].tag = odist[k][kk].tag = sdist[k][kk].tag
= kk;
occ[k] += omark[k][kk].value;
}

score[k] = 0.0;
chair_assg[t][k] = k;

t never gets incremented. You overlay the first row repeatedly. But
then you never use the values so it may not matter.
}

u = 0;
for (k=0; k<SIZE; k++) { //for each chairman, id only, no location
implication
for (kk=0; kk<SIZE; kk++) { //moving to diff location
cost = 0;

for (j=0; j<SIZE; j++) { //objecting other chairmen in other rows
for (jj=0; jj<SIZE; jj++) { //objecting other chairmen in other rows
printf(" a: %d ", assg_under_chair[j][jj] ) ;

Where did assg_under_char[j][jj] get set to a non-zero value?
if ( assg_under_chair[j][jj] == k ) {
cost = cost + ( (odist[kk][jj].value) * (occ[k]) );
printf("3: %lf %lf %lf \n",cost , odist[kk][jj].value , occ[k] );

cost is not a double, more undefined behavior.
break;
}
}
}

}
}
return 0;
}


Remove del for email
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top