更改类的私有部分时的访问冲突写入位置,c ++

时间:2014-03-23 22:14:55

标签: c++ access-violation

我正在写一个Deque(STL不被接受,主要的想法是自己写Deque)。获得:

Unhandled exception at 0x009932C1 in Deque.exe: 0xC0000005:
Access violation writing location 0xFFFFFFFC.

问题在于:

buffer[tail++] = element;

所以,我正在尝试更改一个在课堂上是私有的元素。它有什么问题?

使用Visual Studio 2012,语言 - C ++。 代码:

#include "stdafx.h"
#include <iostream>
#include <cassert>
#include <deque>

using namespace std;

class Deque
{
public:
    void PushBack( int element );
    bool IsEmpty() const { return head == tail; }
    void clearDeque();
    void setBufSize( size_t size )
    {
        bufferSize = size;
        int* buffer = new int[bufferSize];
        for (size_t i = 0; i < bufferSize; i++)
            buffer[i] = 0;
    }
    int getDeque()
    {
        while ( head != tail )
        {
            if ( head == bufferSize )
            {
                head = 0;
            }
            return buffer[head++];
        }
    }
private:
    int* buffer;
    int bufferSize;
    int head;
    int tail;
};

void Deque :: PushBack( int element )
{
    buffer[tail++] = element;
    if ( ( tail == bufferSize ) && ( tail != head ) )
        tail = 0;
}

int main()
{
  Deque myDeque;
  deque <int> TrueDeque;
  myDeque.setBufSize(15);
  myDeque.PushBack(44);
  return 0;
}

5 个答案:

答案 0 :(得分:0)

您应该在构造函数中初始化每个成员。在您的代码中,您使用tail而不首先初始化它,因此它具有一些随机值。

答案 1 :(得分:0)

你究竟在哪里初始化尾巴? (或头)

我建议您在构造函数中执行此操作,以便在需要其他资源时可以利用RAII范例。

答案 2 :(得分:0)

你初始化了头部和尾部。

函数setBufSize也不检查缓冲区是否已经分配。在这种情况下,当您多次调用该函数时会出现内存泄漏。

  void setBufSize( size_t size )
  {
    bufferSize = size;
int* buffer = new int[bufferSize];
for (size_t i = 0; i < bufferSize; i++)
  buffer[i] = 0;
  }

我认为声明中有拼写错误

int* buffer = new int[bufferSize];

应该有

buffer = new int[bufferSize];

如果你的类没有显式的构造函数或者在类定义中添加初始化器,你至少可以在这个成员函数中初始化head和tail。例如

//...
private:
    int* buffer = nullptr;
    int bufferSize = 0;
    int head = 0;
    int tail = 0;

您的类需要定义析构函数,复制赋值运算符和复制构造函数,或者将最后两个定义为已删除。

答案 3 :(得分:0)

您的班级未初始化其数据成员。由于它们都是原始类型(intint*),因此读取它们的值会产生未定义的行为,即任何事情都可能发生,包括随机崩溃。具体来说,在您的情况下,headtail被读取但从未分配或初始化。

您的类需要一个带有初始化列表的构造函数。例如:

Deque::Deque() :
    buffer(0),
    bufferSize(0),
    head(0),
    tail(0)
{
}

实际上,摆脱setBufSize并将其功能直接移到构造函数中(在适用的初始化列表中)。

答案 4 :(得分:0)

(除了其他人已经注意到的关于无法初始化成员变量的问题)

您正在使用具有相同名称的多个变量,可能是无意中的。

在这个成员函数中

void setBufSize( size_t size )
{
    bufferSize = size;
    int* buffer = new int[bufferSize];
    for (size_t i = 0; i < bufferSize; i++)
        buffer[i] = 0;
}

buffer是一个局部变量。您没有使用或更新具有相同名称的成员变量。

尝试使用简单的赋值buffer = new int[bufferSize];而不是变量声明。或者更好的是,改为使用std::vector