调试断言失败,向量下标超出范围

Posted

技术标签:

【中文标题】调试断言失败,向量下标超出范围【英文标题】:Debug Assertion Failed, vector subscript out of range 【发布时间】:2017-06-18 20:47:45 【问题描述】:

我的程序应该在 C++ 中实现一个线程安全堆栈 当我想启动程序时出现错误:

调试断言失败! ...\矢量第 1201 行

表达式:向量下标超出范围

我完全不知道代码有什么问题

#include <condition_variable>
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>

#define NUM_ELEMENTS 10

using namespace std;

class Stack

protected:
    vector<int> stack;
    int topOfStack;    
    int maxSize;
    mutable mutex _mutex;
    mutable condition_variable cv;

public:
    Stack(int size);
    int top() const; 
    int pop(); 
    void push(int element); 

    bool isFull() const;  
    bool isEmpty() const; 
;

Stack::Stack(int size)

    stack.reserve(size); 
    maxSize = size;      
    topOfStack = 0;


int Stack::top() const

    unique_lock<mutex> lck(_mutex);     
    
    // sperren, solange kein Wert da ist
    while (isEmpty())
        cv.wait(lck);

    int val = stack[topOfStack - 1];

    return val;


int Stack::pop()

    // Kritischer Bereich - sperren
    unique_lock<mutex> lck(_mutex);

    // sperren, solange kein Wert am Stack ist
    while (isEmpty())
        cv.wait(lck);

    // Wert zwischenspeichern und Stack-Pointer -1
    // danach werden wartende Threads benachrichtigt
    topOfStack--;
    int val = stack[topOfStack];
    cv.notify_all();

    return val;

void Stack::push(int element)

    // Kritischer Bereich - sperren
    unique_lock<mutex> lck(_mutex);

    // sperren, solange der Stack voll ist
    while (isFull())
        cv.wait(lck);

    // Wert speichern und Stack-Pointer +1
    // danach werden wartende Threads benachrichtigt
    stack[topOfStack] = element;
    topOfStack++;
    cv.notify_all();

bool Stack::isEmpty() const

    return topOfStack == 0;

bool Stack::isFull() const

    return topOfStack == maxSize;


// PRODUCER
class Producer

protected:
    shared_ptr<Stack> stack;

public:
    Producer(shared_ptr<Stack> stack);

    void produce(size_t amount);
;

//CONSUMER
class Consumer

protected:
    shared_ptr<Stack> stack;

public:
    Consumer(shared_ptr<Stack> stack);

    void consume(size_t amount);
;

Producer::Producer(shared_ptr<Stack> stack)
    : stack(stack)

void Producer::produce(size_t amount)

    for (size_t i = 0; i < amount; i++)
    
        cout << "Produce: " << i << endl;
        stack->push(i);
    


Consumer::Consumer(shared_ptr<Stack> stack)
    : stack(stack)

void Consumer::consume(size_t amount)

    for (size_t i = 0; i < amount; i++)
    
        cout << "Consume: " << stack->pop() << endl;
    


// ////////////////////////////////////////////////////////////////////////////

int main()

    shared_ptr<Stack> stack(new Stack(3));

    Producer producer(stack);
    Consumer consumer(stack);

    thread consumerThread(&Consumer::consume, &consumer, NUM_ELEMENTS);
    thread producerThread(&Producer::produce, &producer, NUM_ELEMENTS);

    consumerThread.join();
    producerThread.join();

    return 0;

【问题讨论】:

请edit您的问题提供minimal reproducible example。 我绝对不知道代码有什么问题 -- 错误清楚地向您说明了问题所在。您访问的向量元素超出了该向量中的项目数。 你为什么不使用std::stack,它的行为已经像一个堆栈并为你处理内存?将它打包到一个包装类中,以保护诸如 pop 和 push 之类的关键方法,您基本上就完成了。但是,这样可以避免容易出错的元素处理。 【参考方案1】:

您的vector&lt;int&gt; stack 成员以0 的大小创建,并永远保持0 的大小。我没有看到任何尝试在您的代码中更改其大小。难怪对stack 的任何索引访问都会产生未定义的行为,包括这个“超出范围”错误。

提示:如果你想改变std::vector的大小,对应的方法是resize,而不是reserve。后者改变容量,而不是size向量。

【讨论】:

以上是关于调试断言失败,向量下标超出范围的主要内容,如果未能解决你的问题,请参考以下文章

调试断言失败(向量下标超出范围)

(opencv) 调试断言失败,向量下标超出范围

调试错误 - 向量下标超出范围 - PCL

如何在 Linux 上强制执行向量下标超出范围调试断言

调试断言失败,字符串下标超出范围

unordered_map 在使用 [] 运算符时报告“向量下标超出范围”断言