views:

109

answers:

4

Hi,

I have a class with private member variables declared in a header file. In my constructor, I pass in some filenames and create other objects using those names. This works fine. When I try to add another member variable, however, and initialize it in the constructor, I get an access reading violation. I sent the code to someone else and it works fine on his computer. Any idea what could be wrong?

Here is the offending code:

The .h file:

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();

This is the .cpp file:

#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;


}

I am totally at a loss as to what is causing this - any ideas?

Thanks, bsg

A: 

Have you built clean? Since accessing the last member variable blows up, but assigning to earlier ones works OK, either you're not constructing/allocating the instance right when you do use it, or you have object files that refer to older versions of the header that didn't have qsize in the object yet, and thus aren't allocating enough space. Or something along those lines.

quixoto
I tried cleaning and building several times, but nothing seems to work. I am allowed to assign a value to a member variable in a constructor even if I don't pass in a value designated for it, no?
bsg
@bsg: Yes, you are.
James McNellis
+1  A: 

Your dependencies are probably not right, and the necessary files aren't getting rebuilt. Try a "clean" rebuild.

As a note to style, use initializer lists.

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)
{
}

and you may not need to make those items pointers:

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)
{
}
dash-tom-bang
A: 

As expected, this runs just fine on my machine:

#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;
}

So the error must be in the code you're not showing.

BTW, all upper-case names are boo except for macros. They're making your code harder to read and confuse everyone used to a more common coding style.

sbi
Sorry, I didn't actually write this part of the code - I just tried to modify it by adding the extra variable. And I don't see how the error could be in "the code I'm not showing" because this is the constructor that is called, and it's called in the first line of my program, after declaring the strings that are passed to it. So I'm really stumped.
bsg
@bsg: Well, since the code you showed doesn't contain the error, the only reasonable conclusion must be that the error is in the code you didn't show. A possible scenario where writing to an `int` member variable could fail is if the `this` pointer doesn't point to a valid object. Since you didn't show how you create the object where the constructor fails, the error might be there.
sbi
+2  A: 

Suggestion, factor out the arrays:

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
};

Looks like you should have another structure:

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

And the QueryManager now looks like:

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

This may help encapsulate themes a little better.

Thomas Matthews
+1 good feedback
quixoto