C - 数组代码中的奇怪的Valgrind投诉

时间:2016-03-14 18:01:52

标签: c arrays memory stack valgrind

我有一个支持数组的堆栈实现,适用于我在C中的操作系统课程。我已经确定了所有漏洞,但Valgrind仍在抱怨我无法理解的事情:

import sys
from PyQt5 import QtWidgets
from mainwindow import Ui_MainWindow

class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.closeButton.clicked.connect(self.close)

if __name__ == '__main__':

    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

我的==8162== Invalid read of size 8 ==8162== at 0x400E90: shift_left (stack.c:54) ==8162== by 0x400E90: pop (stack.c:86) ==8162== by 0x40104D: process_rpn (rpn.c:59) ==8162== by 0x4009DF: main (main.c:43) ==8162== Address 0x54f8100 is 0 bytes after a block of size 16 alloc'd ==8162== at 0x4C2AC9B: realloc (vg_replace_malloc.c:785) ==8162== by 0x400E45: resize_internal (stack.c:25) ==8162== by 0x400E45: shift_right (stack.c:40) ==8162== by 0x400E45: push (stack.c:71) ==8162== by 0x400FF3: process_rpn (rpn.c:50) ==8162== by 0x4009DF: main (main.c:43) shift_left例程都会发生这种情况。我的导师和我都无法弄清楚出了什么问题;这是代码。我准备把这个称为Valgrind的假阳性,但在我做之前我想要另一组眼睛:

shift_right

其中// shift internal array elements all left by one void shift_left(stack_t* shift) { for(int i = 0; i < shift->elements; i++) { shift->backing[i] = shift->backing[i + 1]; shift->backing[i + 1] = 0; } } 是如此定义的结构:

stack_t
在插入的情况下,

typedef struct stack_t { double* backing; size_t capacity; size_t elements; } stack_t; 分配了backingmalloc,从而导致支持数组的大小调整。

2 个答案:

答案 0 :(得分:2)

当元素==容量且public interface IFoo { public String getString(); } public class DefaultImpl implements IFoo { public String getString() { return "Default Implementation"; } } public class AnnotatedImpl implements IFoo { public String getString() { return "Annotated Implementation"; } } public class Bindings extends AbstractBinder { @Override public void configure() { ServiceBindingBuilder<DefaultImpl> defaultImpl = bind(DefaultImpl.class) .to(IFoo.class); defaultImpl.ranked(9); ServiceBindingBuilder<AnnotatedImpl> annotatedImpl = bind(AnnotatedImpl.class) .qualifiedBy(new MyAnnotationQualifier()) .to(IFoo.class); annotatedImpl.ranked(1); } } public class MyService { @Inject public MyService( IFoo defaultImplementation, @MyAnnotation IFoo annotatedImplementation) { // ... my code here ... } } 已达到最后一个元素的索引时,

i

...将在已分配的内存之外进行索引。

例如,当(看起来像你的valgrind中的情况),capacity == elements == 2,shift->backing[i + 1] 将循环到1而i将引用{{1这是在分配的数组之外。

答案 1 :(得分:0)

由于多种原因,您的代码不正确:

  • 您可以在数组末尾之外的一个位置访问backing数组。
  • 在复制之前覆盖第二个及后续元素。

以下是更正后的版本:

// shift internal array elements all left by one
void shift_left(stack_t *shift) {
    if (shift->elements > 0) {
        for (int i = 1; i < shift->elements; i++) {
            shift->backing[i - 1] = shift->backing[i];
        }
        shift->backing[shift->elements - 1] = 0;
    }
}