c++ en dehors de la plage à l'emplacement de la mémoire d'erreur
Voici le code que j'ai pour une programmation de l'affectation que j'ai. Im obtenir cette erreur quand je lance le programme
"Exception non gérée à 0x772BC41F dans STRUCT2.EXE: Microsoft C++ exception: std::out_of_range à l'emplacement de la mémoire 0x0043ED04." Si je comprends bien ce droit, l'erreur signifie que mon tableau a dépassé le délai imparti de l'espace mémoire. est-ce exact? et si cela est correct, ce que je fais mal? Mon fichier d'entrée a moins de 30 éléments.
#include "stdafx.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath>
#include <sstream>
#include <cctype>
using namespace std;
struct Element
{
string Name;
char eN1;
char eN2;
float Weight;
};
struct Formula
{
char Element1;
char ElementA;
int Atom;
};
void ELEMENTS(Element ElmAry[30]);
float Str2Float(string Weight);
void FORMULAS(Formula FormAry[30]);
float CalculateMoleculeWeight(Element ElmAry[30], Formula FormAry[30]);
int main()
{
ifstream inputFile1;
ifstream inputFile2;
ofstream outputFile;
inputFile1.open("Element.txt");
inputFile2.open("Formula.txt");
outputFile.open("Molecular Weight.txt");
Element ElmAry[30];
Formula FormAry[30];
char inputCh;
int i = 0;
string String1;
string mFor;
string ABRV;
int ElmDigit = 0;
float StringWeight = 0;
string Name;
string Weight;
int LENGTH = 0;
float MOLEWT;
if(!inputFile1)
{
cout << "Couldn't find the Element.txt file." << endl;
return 0;
}
if(!inputFile2)
{
cout << "Couldn't find the Formula.txt file." << endl;
return 0;
}
ELEMENTS(ElmAry);
while(inputFile1)
{
Name = String1.substr(0,2);
ElmAry[i].Name = Name;
Weight = String1.substr(3,10);
String1.clear();
StringWeight = Str2Float(Weight);
ElmAry[i].Weight = StringWeight;
i++;
}
i--;
FORMULAS(FormAry);
while (inputFile2)
{
getline(inputFile2,String1);
LENGTH = String1.length();
int j = 0;
int n = 0;
while( j < LENGTH)
{
int pos = 0;
pos = String1.find(')');
while(n < LENGTH)
{
inputCh = String1.at(n);
if(isalpha(inputCh) && isupper(inputCh))
{
FormAry[j].Element1 = String1.at(n);
n++;
inputCh = String1.at(n);
}
if(isalpha(inputCh) && islower(inputCh))
{
FormAry[j].ElementA = String1.at(n);
n++;
inputCh = String1.at(n);
}
if(ispunct(inputCh))
{
n++;
inputCh = String1.at(n);
ElmDigit = (inputCh-'0');
}
if(isdigit(inputCh))
{
FormAry[j].Atom = ElmDigit;
n++;
}
inputCh = String1.at(n);
j++;
if(iscntrl(inputCh))
{
n++;
inputCh = String1.at(n);
j++;
}
n++;
}
}
}
MOLEWT = CalculateMoleculeWeight(ElmAry, FormAry);
cout << "\t\t MOLECULAR WEIGHT CHART \t\t\n" << endl;
cout << "\n| FORMULA |\t " << "\t| ATOM.WT |" << endl;
cout << "_______________________________";
outputFile << "\t\t MOLECULAR WEIGHT CHART \t\t\n" << endl;
outputFile << "\n| FORMULA |\t " << "\t| ATOM.WT |" << endl;
outputFile << "_______________________________";
for (int a = 0; a < 30; a++)
{
cout << MOLEWT << endl;
outputFile << MOLEWT << endl;
}
inputFile1.close();
inputFile2.close();
outputFile.close();
cin.get();
cin.get();
return 0;
}
void ELEMENTS(Element ElmAry[30])
{
for(int i = 0; i < 30; i++)
{
ElmAry[i].Weight = 0;
}
}
void FORMULAS(Formula FormAry[30])
{
for(int x = 0; x < 30; x++)
{
for(int x = 0; x < 9; x++)
{
FormAry[x].Atom = 1;
}
}
}
float Str2Float (string x)
{
stringstream ss(x);
float StringWeight;
ss >> StringWeight;
return StringWeight;
}
float CalculateMoleculeWeight(Element ElmAry[30], Formula FormAry[30])
{
int i;
int j=0;
float MoleWT = 0;
float MoleSum = 0;
char e1;
char e2;
char f1;
char f2;
for(i = 0; i < 30; i++)
{
f1 = FormAry[j].Element1;
f2 = FormAry[j].ElementA;
e1 = ElmAry[i].eN1;
e2 = ElmAry[i].eN1;
if
(e1 == f1 && e2 == f2)
{
MoleWT = ElmAry[i].Weight * FormAry[j].Atom;
MoleSum = MoleSum + MoleWT;
j++;
}
}
return MoleSum;
}
quand j'arrive à
while(inputFile1)
{
Name = String1.substr(0,2);
ElmAry[i].Name = Name;
Weight = String1.substr(3,10);//invalid string position
String1.clear();
StringWeight = Str2Float(Weight);
ElmAry[i].Weight = StringWeight;
i++;
}
i--;
Poids = Mot1.substr(3,10); me donne une chaîne non valide position
- Saint-code dump, Batman!
- Beaucoup trop de code. Faire un effort et affiner votre problème.
- Exécuter sous un débogueur. Trouver où il AV. Fix it.
- Dans votre deuxième extrait de code, vous n'avez pas initialisé
String1
à rien, rien d'étonnant à cela en vous donnant une erreur, c'est vide.
Vous devez vous connecter pour publier un commentaire.
std::out_of_range
est une exception que vous obtenez lorsque vous essayez d'accéder à la mémoire en dehors de l'espace que vous avez alloué (dans un conteneur STL). Dans ce cas particulier, vous accédez à des zones destd::string
qui n'a pas été attribué:std::string::substr
prend index des paramètres qui doivent être dans les limites de la matrice encapsulé parstd::string
. Si la chaîne est à seulement 2 caractères, et vous tentez d'obtenir des caractères commençant à la 4ème position, vous verrez lastd::out_of_range
exception. Vous devriez vérifier lelength
avant de faire ce genre d'opération.En outre, vous déclarez vos tableaux:
Mais vous êtes en boucle au travers d'un fichier (qui potentiellement a plus de 30 éléments). Ainsi, lorsque
i >= 30
, vous êtes hors des limites du terrain (et le comportement ne sera pas défini).Vous pouvez corriger cela en utilisant
std::vector
, ce qui permettra à la matrice de dynamique de taille moyenne, ou une autre collection (par exemple,std::list
,std::deque
).out_of_range
, quand vous allez au delà de la fin il a juste invoque UB.std::string::substr(3, 10)
sur une chaîne vide est beaucoup plus probable candidat (surtout depuis l'OP t dire que c'est l'endroit où l'erreur se produit).substr
est aussi une mauvaise.out_of_range
n'est levée sipos
(le premier argument) est strictement plus grande que la chaîne de caractères de taille. Le comte (deuxième argument) est tout simplement fixe si(pos + count) > size()
. Si le premier appelsubstr(0, 2)
réussira toujours, même sur une chaîne vide. Voir cette doc. Comme VS lancer en mode debug, ils sont autorisés à le faire que parce que l'opération est UB en premier lieu, mais c'est certainement pas le C++ spécification.Name = String1.substr(0,2);
ne cause pas un problème sur une chaîne vide, il va traiter que2
comme un maximum.