2010-04-09 14 views
1

J'ai une classe avec des variables de membre privées déclarées dans un fichier d'en-tête. Dans mon constructeur, je passe certains noms de fichiers et crée d'autres objets en utilisant ces noms. Cela fonctionne bien. Cependant, lorsque j'essaie d'ajouter une autre variable membre et de l'initialiser dans le constructeur, j'obtiens une violation de lecture d'accès. J'ai envoyé le code à quelqu'un d'autre et cela fonctionne très bien sur son ordinateur. Une idée de ce qui pourrait être faux?Erreur de lecture d'accès lors de l'utilisation de la variable de membre de classe

Voici le code incriminé:

Le fichier .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(); 

Ceci est le fichier .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; 


} 

Je suis tout à fait à une perte de ce qui est provoquant ceci - des idées?

Merci, bsg

+0

Il peut être important de voir comment vous instanciez la classe. – spoulson

Répondre

0

Avez-vous construit propre? Puisque l'accès à la dernière variable membre explose, mais que l'affectation aux versions précédentes fonctionne correctement, soit vous ne construisez pas/allouez l'instance juste quand vous l'utilisez, soit vous avez des fichiers objets qui se réfèrent à des versions antérieures de l'en-tête t ont encore qsize dans l'objet, et n'attribuent donc pas assez d'espace. Ou quelque chose de ce genre.

+0

J'ai essayé de nettoyer et de construire plusieurs fois, mais rien ne semble fonctionner. Je suis autorisé à attribuer une valeur à une variable membre dans un constructeur même si je ne transmets pas une valeur désignée pour cela, non? – bsg

+0

@bsg: Oui, vous l'êtes. –

1

Vos dépendances ne sont probablement pas correctes et les fichiers nécessaires ne sont pas reconstruits. Essayez une reconstruction "propre".

Comme note de style, utilisez les listes d'initialisation.

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

et vous ne pouvez pas besoin de faire ces pointeurs articles:

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

Comme prévu, cela va très bien sur ma 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; 
} 

Ainsi, l'erreur doit être dans le code que vous ne montrez pas.

BTW, tous les noms de majuscules sont boo, sauf pour les macros. Ils rendent votre code plus difficile à lire et à confondre avec tout le monde habitué à un style de codage plus commun.

+0

Désolé, je n'ai pas réellement écrit cette partie du code - j'ai juste essayé de le modifier en ajoutant la variable supplémentaire.Et je ne vois pas comment l'erreur pourrait être dans "le code que je ne montre pas" parce que c'est le constructeur qui est appelé, et il est appelé dans la première ligne de mon programme, après avoir déclaré les chaînes qui lui sont passées . Donc je suis vraiment perplexe. – bsg

+0

@bsg: Eh bien, puisque le code que vous avez montré ne contient pas l'erreur, la seule conclusion raisonnable doit être que l'erreur est dans le code que vous n'avez pas montré. Un scénario possible où l'écriture dans une variable membre 'int' pourrait échouer est si le pointeur' this' ne pointe pas vers un objet valide. Puisque vous n'avez pas montré comment vous créez l'objet où le constructeur échoue, l'erreur pourrait être là. – sbi

2

Suggestion, facteur les tableaux:

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

On dirait que vous devriez avoir une autre structure:

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

Et le QueryManager ressemble maintenant:

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

Cela peut aider encapsuler les thèmes un peu mieux.

+0

+1 très bonne évaluation –