c - 奇怪的内存问题?

标签 c linux memory gcc

我遇到了一个有趣的问题,我希望这完全是我的错。

我有从队列中读取的代码,如:

 do {
    evt       = &newevts[ evt_head++ ];
    evt_head &=  MAX_EVENTS;

    if (evt->index <= 0 || evt->index > MAX_INDEX) {
         printf("RX EVENT BAD NDX: ndx=%d h=%d\n",evt->index, evt_head);
         continue;
    }

    //... etc ...

 } while(evt_head != evt_tail) ;

奇怪的问题是 if 语句可以评估 evt->index 是一个错误的值,但是当 printf 显示时它显示了一个完全有效的值!示例:

RX EVENT BAD NDX: ndx=1 h=64

if 语句清楚地表明条件必须是 <= 0 OR > 1024(最大索引)。更糟糕的是,这只会偶尔发生一次。我正在使用 GCC、Centos 6.3。除此线程外,没有线程接触 evt_head。 (为了确定,我已将其重命名几次并重新编译。)

尾部由一个函数处理,该函数将项目添加到队列的方式与头部删除它们的方式相同(递增然后 AND)。我还在事件结构本身内部添加了一个计数器,以记录头/尾值,因为事件被放入队列并且没有发现丢失或跳过的值。从字面上看,我好像读到了一些不好的内存。但这太荒谬了 - 如果是这样的话,我希望系统崩溃或至少程序崩溃。

关于这在世界上如何偶尔发生的任何想法? (频率大约是 100 次读取中的 1 次)我感谢任何输入!

typedef struct {
    int    index;
    int    event;
} EVENT;

#define  MAX_EVENTS  0x01ff
#define  MAX_INDEX   1024

没有线程或其他代码接触 evt_head。只有这个循环。队列永远不会满。我也碰巧在进入添加到队列的例程时有一个“自旋锁”(为以后被其他线程访问做准备),并在退出时有一个解锁。

最佳答案

我的猜测是,将事件添加到尾部的函数会在写入 index 字段之前更改 evt_tail。这允许您的读者访问仍在编写过程中的事件。

关于c - 奇怪的内存问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14451934/

相关文章:

c - Mmap 不使用给定的地址

c - 如何防止 Windows WriteConsole() 默认使用宽字符

c - 我们如何使用一个 malloc 语句分配一个二维数组

linux - 更改公共(public) HTML 中的所有者和组

c++ - 在c++中使用x64系统和x86应用程序分配大内存

c - #ifdef 需要查询和说明

linux - 如何通过grep命令搜索包含数字的字符串

c - 如何检查文件是否完全到达/复制?

memory - 内存通常比磁盘快多少?

memory - 硬件和编译器如何处理跨入不可执行页面的 x86 指令?