unpredictable deterministic behaviour again

Discussion in 'C Programming' started by a, Nov 29, 2007.

  1. a

    a Guest

    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, Nov 29, 2007
    #1
    1. Advertising

  2. a

    a Guest

    PS

    > 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.
     
    a, Nov 29, 2007
    #2
    1. Advertising

  3. a

    James Kuyper Guest

    a wrote:
    > 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.
     
    James Kuyper, Nov 29, 2007
    #3
  4. a

    a Guest

    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;
    }
     
    a, Nov 29, 2007
    #4
  5. a

    James Kuyper Guest

    a wrote:
    > 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.
     
    James Kuyper, Nov 29, 2007
    #5
  6. On Thu, 29 Nov 2007 21:23:22 +0800, "a" <> wrote:

    >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
     
    Barry Schwarz, Dec 1, 2007
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    381
    Patrick TJ McPhee
    Nov 5, 2003
  2. Andrew

    Unpredictable program behavior ..

    Andrew, Dec 6, 2003, in forum: C Programming
    Replies:
    3
    Views:
    384
    Andrew
    Dec 7, 2003
  3. Replies:
    44
    Views:
    988
  4. Replies:
    8
    Views:
    484
    red floyd
    May 17, 2006
  5. Replies:
    5
    Views:
    354
    Ron Natalie
    Jan 11, 2008
Loading...

Share This Page