【问题标题】:Access reading error when using class member variable使用类成员变量时访问读取错误
【发布时间】:2010-04-09 15:44:21
【问题描述】:

我有一个在头文件中声明的私有成员变量的类。在我的构造函数中,我传入一些文件名并使用这些名称创建其他对象。这工作正常。但是,当我尝试添加另一个成员变量并在构造函数中对其进行初始化时,我遇到了访问读取冲突。我将代码发送给其他人,它在他的计算机上运行良好。知道有什么问题吗?

这是有问题的代码:

.h 文件:

class QUERYMANAGER {
    INDEXCACHE *cache;
    URLTABLE *table;
    SNIPPET *snip;
    int* iquery[MAX_QUERY_LENGTH];
    int* metapointers[MAX_QUERY_LENGTH];
    int blockpointers[MAX_QUERY_LENGTH];
    int docpositions[MAX_QUERY_LENGTH];
    int numberdocs[MAX_QUERY_LENGTH];
    int frequencies[MAX_QUERY_LENGTH];
    int docarrays[MAX_QUERY_LENGTH][256];
    int qsize;



public:
    QUERYMANAGER();
    QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname);
    ~QUERYMANAGER();

这是 .cpp 文件:

#include "querymanagernew.h"
#include "snippet.h"
using namespace std;



QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname){
    cache = new INDEXCACHE(indexfname, btfname);
    table = new URLTABLE(urltablefname);
    snip = new SNIPPET(snippetfname, snippetbtfname);

    //this is where the error occurs
    qsize = 0;


}

我完全不知道是什么原因造成的 - 有什么想法吗?

谢谢,bsg

【问题讨论】:

  • 看看你是如何实例化类的可能很重要。

标签: c++ header-files access-violation member-variables


【解决方案1】:

建议,排除数组:

class QUERYMANAGER
{
// Snip
    int* iquery[MAX_QUERY_LENGTH];
    int* metapointers[MAX_QUERY_LENGTH];
    int blockpointers[MAX_QUERY_LENGTH];
    int docpositions[MAX_QUERY_LENGTH];
    int numberdocs[MAX_QUERY_LENGTH];
    int frequencies[MAX_QUERY_LENGTH];
    int docarrays[MAX_QUERY_LENGTH][256];
    int qsize;
// Snip
};

看起来你应该有另一个结构:

struct Info
{
    int* iquery;
    int* metapointers;
    int blockpointers;
    int docpositions;
    int numberdocs;
    int frequencies;
    int docarrays[256];
};

QueryManager 现在看起来像:

class QueryManager
{
    INDEXCACHE *cache;
    URLTABLE *table;
    SNIPPET *snip;
    int qsize;
    Info  details[MAX_QUERY_LENGTH];
};

这可能有助于更好地封装主题。

【讨论】:

    【解决方案2】:

    您的依赖关系可能不正确,并且没有重建必要的文件。尝试“干净”的重建。

    作为样式说明,请使用初始化列表。

    QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname,
                               char *snippetfname, char *snippetbtfname) :
        cache(new INDEXCACHE(indexfname, btfname)),
        table(new URLTABLE(urltablefname)),
        snip(new SNIPPET(snippetfname, snippetbtfname)),
        qsize(0)
    {
    }
    

    而且您可能不需要将这些项目设为指针:

    class QUERYMANAGER {
        INDEXCACHE cache;
        URLTABLE table;
        SNIPPET snip;
    ...
    
    QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname,
                               char *snippetfname, char *snippetbtfname) :
        cache(indexfname, btfname),
        table(urltablefname),
        snip(snippetfname, snippetbtfname),
        qsize(0)
    {
    }
    

    【讨论】:

      【解决方案3】:

      你建得干净吗?由于访问最后一个成员变量会爆炸,但分配给较早的成员变量可以正常工作,要么您在使用它时没有正确构造/分配实例,要么您有引用旧版本的标头的目标文件没有'对象中还没有qsize,因此没有分配足够的空间。或者类似的东西。

      【讨论】:

      • 我尝试了几次清洁和建造,但似乎没有任何效果。即使我没有传入为它指定的值,我也可以在构造函数中为成员变量赋值,不是吗?
      【解决方案4】:

      正如预期的那样,这在我的机器上运行得很好:

      #include <cstdlib>
      
      struct INDEXCACHE {};
      struct URLTABLE {};
      struct SNIPPET {};
      
      const std::size_t MAX_QUERY_LENGTH = 256;
      
      class QUERYMANAGER {
          INDEXCACHE *cache;
          URLTABLE *table;
          SNIPPET *snip;
          int* iquery[MAX_QUERY_LENGTH];
          int* metapointers[MAX_QUERY_LENGTH];
          int blockpointers[MAX_QUERY_LENGTH];
          int docpositions[MAX_QUERY_LENGTH];
          int numberdocs[MAX_QUERY_LENGTH];
          int frequencies[MAX_QUERY_LENGTH];
          int docarrays[MAX_QUERY_LENGTH][256];
          int qsize;
      
      
      
      public:
          QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname);
      };
      
      QUERYMANAGER::QUERYMANAGER(char *indexfname, char *btfname, char *urltablefname, char *snippetfname, char *snippetbtfname)
          : cache(new INDEXCACHE(/*indexfname, btfname*/))
          , table(new URLTABLE(/*urltablefname*/))
          , snip(new SNIPPET(/*snippetfname, snippetbtfname*/))
          , qsize(0)
      {
      }
      
      int main()
      {
          QUERYMANAGER foo("blargl", "frxnl", "wrgxl", "brlgl", "srgl");
          return 0;
      }
      

      所以错误必须在您未显示的代码中。

      顺便说一句,除了宏,所有大写名称都是 boo。它们使您的代码更难阅读,并使习惯于更常见编码风格的每个人感到困惑。

      【讨论】:

      • 对不起,这部分代码我实际上并没有写——我只是尝试通过添加额外的变量来修改它。而且我看不到“我没有显示的代码”中的错误是如何出现的,因为这是被调用的构造函数,并且在声明传递给它的字符串之后,它在我的程序的第一行中被调用.所以我真的很难过。
      • @bsg:好吧,既然你显示的代码不包含错误,唯一合理的结论必须是错误在你没有显示的代码中。写入int 成员变量可能失败的一种可能情况是this 指针未指向有效对象。由于您没有展示如何创建构造函数失败的对象,因此可能存在错误。
      猜你喜欢
      • 2016-09-18
      • 2023-03-02
      • 2019-08-02
      • 1970-01-01
      • 2016-02-07
      • 1970-01-01
      • 1970-01-01
      • 2018-03-19
      • 2020-01-26
      相关资源
      最近更新 更多