swicano
swicano

Reputation: 85

need help finding why a for loop's counter variable is being altered by a function inside the loop

a function inside my loop is somehow changing the value that i am iterating over, and i'm not sure how. i'm sorry if this is very poorly described.

inside this for loop

int k;

for( k = 0; k < 512; k++)
{
    // Discardheader(d);      // doesnt actually do anything, since it's a header.f
    int databit = Getexpecteddata(d+4*k+1);
    printf("%d ",k);
    int transmitted = Datasample(&datastate, &datalength, d+4*k+2,dataerr,dataloc, databit);
    printf("%d ",k);
    Clocksample(&clockstate, &clocklength, d+4*k+3,clockerr, transmitted); 
    printf("%d \n",k);

}

i get this output

16 16 16
17 17 17
18 18 18
19 19 19
20 20 20
21 1 1
2 2 2
3 3 3
4 4 4

so somehow Datasample is changing the value of k once it reaches 21. d is type char * d and represents a buffer where i read a file in. changing input files does not change that at 21 the switch happens. here is the code for datasample:

int Datasample (int* state, int* length, char *d, int *type, int location, int data)
{
    int match = 1;                                  // if data sample and delayed tx match,
    if ( ((d[0] >> location) & 1) != data)
    {
        match = 0;
        if(data)
    {
        type[2]++;  
    }
    else
    {
        type[1]++;
    }   

} 

int ia;
for( ia = 7; ia>=0; ia--)                           
{
    if ( ((d[0] >> ia) & 1) == *state)          // finds an edge
    {
        *length++;
    }
    else
    {
        int distance, deviation,devflag=1;      // distance the edge is from the sample point. should be about 4
        if ( location > 3)                      // deviation is how far the distance then is from 4
        {distance = location - ia;}
        else
        {distance = ia - location;}

        deviation = abs(4-distance);

        if( (deviation >= devmax) && match && devflag)
        {
            devflag =0;    
            if(data)
            {
                type[2]++;  
            }
            else
            {   
                type[1]++;
            }   

        }
        *state = ((d[0] >> ia) & 1);
        *length = 1;
    }

}

return ((d[0] >> location) & 1);

}

what is causing the k to roll back to 1 once it hits 21?

thanks in advance. i have no idea what i'm doing.

Upvotes: 3

Views: 216

Answers (5)

wildplasser
wildplasser

Reputation: 44250

I don't have the faintest idea what the program is supposed to do (comments don't help very much, the variable names are not that descriptive). The main problem appears to be the *lenght++; statement, which bumps the pointer beyond recognition. A subsequent *length = 1; does the dirty work.

Extra comment on style: it is preferable to perform bit operations on unsigned types; sign-extention could cause '1' bits to appear at unwanted places. Also: it is advisable to use unsigned types for counters and indexes; that will cause the program to crash more rigorously on underflow.

int Datasample (int *state, int *length, char *d, int *type, unsigned location, int data)
{
    int match = 1;                                  // if data sample and delayed tx match,
    int devflag = 1;        /* hoisted this variable from inner loop */
    unsigned bitpos ;     /* renamed and changed to unsigned ( location as well) */

                          /* Note: shift by zero (or negative) is undefined */
    if ( ((d[0] >> location) & 1) != data) {
        match = 0;
        if(data) type[2]++;
        else type[1]++;
    } 
                        /* Again: shift by zero is undefined */
    for( bitpos = 8; bitpos-- > 0; )                           
    {
          // find an edge
        if ( ((d[0] >> bitpos) & 1) == *state) *length += 1;
        else
        {
            int distance, deviation;
                                  // distance the edge is from the sample point. should be about 4
                                  // deviation is how far the distance then is from 4
            distance = (location > 3) ?  location - bitpos : bitpos - location;
            deviation = abs(4-distance);

            if (deviation >= devmax && match && devflag)
            {
                devflag =0;    
                if (data) type[2]++;
                else type[1]++;
            }
            *state = ((d[0] >> bitpos) & 1);
            *length = 1;
        }

    }

    return ((d[0] >> location) & 1);
}

BTW is this the expected output for 0_patterns ?

 File contains 5769 events 
 File contains 6938 errors 
 File contains 543 spill errors 
 File contains 6395 nonspill errors 
    Error       nonspill #  spill #     
    Type D      2250        451         
    Type C      0       0           
    Type B      4145        92          

    Case 1      1195        307         
    Case 2      0       20          
    Case 3      1055        124         
    Case 4      0       0           
    Case 5      0       0           
    Case 6      0       0           
    Case 7      0       0           
    Case 8      1160        9           
    Case 9      0       0           
    Case 10a    1472        39          
    Case 10b    1513        29          
    Case 10c    0       15

Upvotes: 1

Gangnus
Gangnus

Reputation: 24464

It's obvious, according to output, that you are writing into some array that starts 16 elements before k.

Upvotes: 0

KKK
KKK

Reputation: 1085

Where and how do you delare dataerr? My guess is as you are modifying data err in the function it then overflows the size of dataerr which probably then affects the variable k.

Upvotes: 0

cnicutar
cnicutar

Reputation: 182639

Looking at your output it's quite possible the Datasample function does something funny with the memory.

The first problem I see is that you're passing an integer as the third argument of the function and a pointer is expected. Which leads me to believe you're compiling without warnings turned on. Which is the real problem.

EDIT

In light of recent comments it turns out d is actually a pointer. However, I stand by my opinion that something in that function writes over k.

Since gcc on Linux is being used you could try valgrind to quickly pinpoint the problem. It should warn you about illegal accesses to memory.

Upvotes: 5

Use a debugger, like e.g. gdb on Linux, and set a watchpoint on k; perhaps some called routine is overflowing its call stack....

Upvotes: 3

Related Questions