2012-02-11 3 views
0

Ok, donc je fais un programme pour la classe lorsque je rencontre un bug que je n'ai jamais vu auparavant et aucune idée de ce qu'il faut faire avec une expérience minimale avec l'utilisation du débogueur, donc Je suis venu ici en espérant que quelqu'un ici puisse me fixer le chemin pour corriger ce bug. Mon bug est l'emplacement de lecture de la violation d'accès. Voici la partie du code qui semble me donner l'erreur:Accédez à l'emplacement de lecture de violation avec le programme simple

#include "Book.h" 

using namespace std; 

void add (char*, char*, int); 
void remove (int&); 
void list(); 

int Count; 



Book Bookshelf [4]; 

int main() 
{ 
    char* In = ""; 
    char* N = ""; 
    char* A = ""; 
    int Y; 
    int Num; 

    do 
    { 
     cout << "Bookshelf> "; 
     cin >> In; 

     if (In == "add") 
     { 
      cout << "Bookshelf> Enter book: "; 
      cin >> N >> A >> Y; 
      add (N,A,Y); 
     } 

     else if (In == "remove") 
     { 
      cout << "Bookshelf> Select number: "; 
      cin >> Num; 
      remove (Num); 
     } 

     else if (In == "list") 
     { 
     } 

    } while (cin != "quit"); 

    return 0; 
} 

void add (char* N, char* A, int Y) 
{ 
    if (Bookshelf[4].IsEmpty() == false) 
     cout << "Error!" << endl; 
    else 
    { 
     Bookshelf[Count] = Book (N,A,Y); 
     Count++; 
    } 
    cout << "Bookshelf> "; 
} 

Je reçois l'erreur quand je tape ajouter dans la ligne de commande pour essayer d'appeler la fonction d'ajout, mais il se produit immédiatement si le débogueur est pas aide-moi. Je sais que le problème est probablement très simple mais je n'arrive pas à le trouver. Toute aide que vous pouvez offrir serait grandement appréciée. Faites-moi savoir si d'autres échantillons de code sont nécessaires.

+2

Jetez un oeil à l'utilisation de 'std :: string' –

Répondre

2

Vous shouldn » t utilisez char* sauf si vous savez vraiment ce que vous faites. Par exemple, j'utilise rarement char* et je programme avec C++ depuis environ 20 ans. Vous voulez utiliser std::string, par ex. comme ceci:

std::string In; 
if (std::cin >> In) { ... } 

La raison pour laquelle votre code ne fonctionne pas est que l'opérateur d'entrée souhaite stocker des données à l'endroit indiqué par le pointeur. Cependant, ce pointeur pointe vers une mémoire immuable pour un littéral de chaîne de caractères. Lorsque l'opérateur essaie de stocker quelque chose à cet endroit, il obtient immédiatement une violation d'accès.

La solution la plus simple consiste à utiliser std::string. Si vous ne pouvez pas utiliser std::string pour une raison quelconque, utilisez un tableau préalloué de char. Si vous faites cela, assurez-vous dire le flux combien de caractères sont disponibles par la mise en place de la largeur:

char In[16]; 
if (std::cin >> std::setw(sizeof(In)) >> In) { ... } 

(la raison pour laquelle je suis toujours à l'aide d'un chèque dans ces exemples est qu'il est très important que vous vérifiez toujours si votre entrée a réussi avant de faire quoi que ce soit avec le résultat).

+0

Ok merci, ma nouvelle question est: est-ce que mon cin >> A >> Y travaille toujours pour lire une seule ligne délimitée par des espaces si je passe à std :: string? – triple07

+1

@ triple07: Oui. – ildjarn

+0

@ildjarn Ok maintenant mon compilateur se plaint qu'il ne peut pas convertir le paramètre 1 de std :: string en char * sur la ligne suivante avec add (N, A, Y) qui accepte 2 std :: strings et un int. Des idées? – triple07

1

Vous ne pouvez pas écrire de données dans l'espace alloué pour les littéraux de chaîne de caractères: ce sont des constantes. Ce est la partie qui mène à ce comportement:

char* In = ""; 
cin >> In; 

Deux choses sont mal:

  1. votre variable In ne dispose pas de suffisamment d'espace pour une chaîne non vide.
  2. Même si c'était le cas, l'écriture dans cet espace ne serait pas autorisée.

Pour résoudre ce problème, vous pouvez soit (1) passer à l'utilisation std::string (recommandé) ou (2) modifier les déclarations de vos chaînes de C à des tableaux de caractères, comme ceci:

char In[128]; 
+1

Ne mentionnez même pas' MAGIC_BUFFER_SIZE'. – Puppy

+1

Je vois, merci, je vais essayer de passer à std :: string. – triple07

+0

@DeadMG Pourquoi pas? Recommander c'est une chose, mais ne pas le mentionner est trop. C'est une fonctionnalité de langue que vous le vouliez ou non, et il est entièrement pris en charge par la bibliothèque - encore une fois, que cela vous plaise ou non. Je ne l'aime pas, mais je crois que les programmeurs doivent être conscients et éviter cette fonctionnalité * consciemment *, par opposition à parce qu'ils ne savent tout simplement pas à ce sujet. – dasblinkenlight

Questions connexes