【问题标题】:need help finding why a for loop's counter variable is being altered by a function inside the loop需要帮助找出为什么循环内的函数正在更改 for 循环的计数器变量
【发布时间】:2011-12-30 08:05:47
【问题描述】:

我的循环中的一个函数以某种方式改变了我正在迭代的值,我不确定如何。如果这描述得很糟糕,我很抱歉。

在这个for循环中

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);

}

我得到这个输出

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

所以一旦达到 21,Datasample 就会以某种方式更改 k 的值。d 是 char * d 类型,表示我在其中读取文件的缓冲区。更改输入文件不会改变在 21 发生切换的情况。这是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);

}

是什么导致 k 在达到 21 后回滚到 1?

提前致谢。我不知道我在做什么。

【问题讨论】:

  • 不用想太多……k变量的类型是什么?它是一个 int 还是一个简单的 char(或最终是一个字节)?
  • 哦,k 只是一个 int,我在上面声明了 2 行。对不起。
  • 您的第三个参数是指向字符的指针 - d 是什么?你确定不是在那里践踏东西吗?
  • d 是 char * d 类型,它是一个指向我读取文件的缓冲区的指针。
  • d 有多大...?你是怎么分配的?

标签: c for-loop


【解决方案1】:

看看你的输出,Datasample 函数很可能对内存做了一些有趣的事情。

我看到的第一个问题是您将整数作为函数的第三个参数传递,并且需要一个指针。这让我相信你在编译时没有打开警告。这是真正的问题

编辑

根据最近的 cmets 事实证明 d 实际上是一个指针。但是,我坚持认为该函数中的某些内容会覆盖 k

由于在 Linux 上使用 gcc,您可以尝试 valgrind 快​​速查明问题。它应该警告您非法访问内存。

【讨论】:

  • 他知道这一点,他在问什么。
  • 嗯 d 是一个指针 (char * d) 不是吗?如果我想查看 d 指向的缓冲区的第 4*k+2 个字节,我还能如何将其传递进去?它是由另一个运行良好的程序以这种方式处理的。虽然也许他只是幸运,但我如何打开警告?我使用 gcc 通过 ssh 在学校服务器上编译
  • @swicano 对不起,我不知道 d 是一个指针。但要回答你的问题,你可以说&amp;d[4*k + 2]
  • @swicano gcc -Wall -Wextra -o program program.c.
  • 现在 k 在 5 处变回 1,所以它肯定是内存泄漏错误。感谢您的帮助,我会尝试使用 valgrind 找到它。
【解决方案2】:

使用调试器,例如在 Linux 上gdb,并在k 上设置一个观察点;也许一些被调用的例程溢出了它的调用堆栈....

【讨论】:

    【解决方案3】:

    我一点也不知道程序应该做什么(cmets 没有多大帮助,变量名没有那么描述性)。主要问题似乎是*lenght++; 语句,它将指针撞得面目全非。随后的*length = 1; 会做这些脏活。

    对样式的补充说明:最好对unsigned类型进行位操作;符号扩展可能会导致“1”位出现在不需要的位置。另外:建议对计数器和索引使用无符号类型;这将导致程序在下溢时更严格地崩溃。

    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);
    }
    

    顺便说一句,这是 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
    

    【讨论】:

    • 这个程序的要点是他们(我的教授等)生成一个双相标记代码信号(en.wikipedia.org/wiki/Differential_Manchester_encoding),通过暴露在 LHC 质子束下的探测器运行它,样本每个时钟周期 8 次,并确定信号中的单个位何时受到质子的影响,从而考虑到组件本身产生的噪声。以防你好奇。看起来它的 *length++ 优先级部分我搞砸了,希望它现在可以工作。谢谢你向我指出。我也会修复未签名的部分
    • 如果出于某种原因您仍然感兴趣。这是我试图复制其结果的论文hep.physik.uni-siegen.de/atlas/docs/…
    • 谢谢,我会调查的。顺便说一句,*length++ 侥幸也出现在(至少)代码的另一部分中。
    • 如果我理解正确的话,曼彻斯特编码基本上是一个非异或,有很多优化的机会......我是否需要 both 数据文件进行重建和检测信号?
    • bump 我想我修复了代码。并清理了一下。我应该把它上传到某个地方吗?
    【解决方案4】:

    您在哪里以及如何解除数据错误?我的猜测是,当您在函数中修改数据错误时,它会溢出数据错误的大小,这可能会影响变量 k。

    【讨论】:

    • 数据错误为int dataerr[13]
    • 看起来足够大,在该函数中唯一改变的其他变量是数据状态和数据长度。这些是如何声明的?上面有几行声明 int k;
    【解决方案5】:

    根据输出,很明显,您正在写入某个数组,该数组在 k 之前开始 16 个元素。

    【讨论】:

      猜你喜欢
      • 2018-12-01
      • 1970-01-01
      • 2013-10-17
      • 2017-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-01
      相关资源
      最近更新 更多