2017-01-10 2 views
-2

J'ai un programme qui continue à donner une sortie étrange. La sortie était censée être "110". Quel est le problème?Corruption de mémoire de chaîne dans le programme C++

Il est supposé lire un nombre dans un fichier et générer le nombre le plus élevé plus grand que l'entrée qui a la somme de tous les chiffres sur des positions inégales égale à la somme de tous les chiffres sur des positions paires. L'entrée est "99".

EDIT: Fixe! Je posterai une réponse expliquant!

Voici le DE TRAVAIL Code:

//c++11 
#include <iostream> 
#include <fstream> 
#include <cmath> 
#include <string> 
#include <sstream> 
using std::cout; 
using std::string; 
int main(){ 
    string nmbr; 
    { 
     std::ifstream in("ech.in"); 
     in >> nmbr; 
    } 
    enum Equality{ 
     uneven, even, equal 
    }; 
    Equality eq = uneven; 
    int amount; 
    { 
     short int evn = 0; 
     short int unevn = 0; 
     for(unsigned int x = 0;x < nmbr.size();x++){ 
      if(eq == even){ 
       evn += (nmbr[x] - '0'); 
       eq = uneven; 
      }else{ 
       unevn += (nmbr[x] - '0'); 
       eq = even; 
      } 
     } 
     amount = evn - unevn; 
     if(amount < 0){ 
      amount = amount * -1; 
     } 
     if(evn == unevn){ 
      eq = equal; 
     }else if(evn > unevn){ 
      eq = uneven; 
     }else{ 
      eq = even; 
     } 
    } 
    if(eq == equal){ 
     int i; 
     for(i = nmbr.size() - 1;i >= -1;i--){ 
      if(i < 0){ 
       nmbr = "1" + nmbr; 
       break; 
      } 
      if(nmbr[i] != '9'){ 
       nmbr[i] = std::to_string((nmbr[i] - '0') + 1)[0]; 
       break; 
      }else{ 
       nmbr[i] = '0'; 
      } 
     } 
     int sum = 0; 
     int sum1 = 0; 
     for(int x = nmbr.size() - 1;x >= 0;x -= 2){ 
      sum += (nmbr[x] - '0'); 
     } 
     for(int x = nmbr.size() - 2;x >= 0;x -= 2){ 
      sum1 += (nmbr[x] - '0'); 
     } 
     bool diff = true; 
     int diff1 = sum - sum1; 
     if(diff1 < 0){ 
      diff1 *= -1; 
      diff = false; 
     } 
     if(diff1 == 0){ 
      goto output; 
     }else{ 
      i = nmbr.size() - 1; 
      if(diff)i--; 
      for(;i >= -2;i -= 2){ 
       if(i == -1){ 
        std::stringstream ss; 
        ss << diff1 << nmbr; 
        nmbr = ss.str(); 
       }else if(i == -2){ 
        std::stringstream ss; 
        ss << diff1 * 10; 
        ss << nmbr; 
        nmbr = ss.str(); 
       } 
       int add = 9 - (nmbr[i] - '0'); 
       if(add < diff1){ 
        diff1 -= add; 
        nmbr[i] = '9'; 
       }else{ 
        nmbr[i] = std::to_string((nmbr[i] - '0') + diff1)[0]; 
        break; 
       } 
      } 
     } 
    }else{ 
     int i; 
     { 
      bool b = (nmbr.size() % 2) == 0; 
      if(eq == uneven){ 
       if(b) 
        i = nmbr.size() - 2; 
       else 
        i = nmbr.size() - 1; 
      }else{ 
       if(b) 
        i = nmbr.size() - 1; 
       else 
        i = nmbr.size() - 2; 
      } 
     } 
     for(;i >= -1;i -= 2){ 
      if(i < 0){ 
       for(int pow = 0;true;pow += 2){ 
        if(amount > 9){ 
         amount -= 9; 
         nmbr = std::to_string(9 * std::pow(1, pow)) + nmbr; 
        }else{ 
         nmbr = std::to_string(amount * std::pow(1, pow)); 
         break; 
        } 
       } 
       break; 
      } 
      int add = 9 - (nmbr[i] - '0'); 
      if(add > amount){ 
       amount -= add; 
       nmbr[i] = '9'; 
      }else{ 
       nmbr[i] = std::to_string(amount + (nmbr[i] - '0'))[0]; 
       break; 
      } 
     } 
    } 
    output: std::ofstream out("ech.out"); 
    out << nmbr; 
    return 0; 
} 

Voici le code cassé d'origine:

//c++11 
#include <iostream> 
#include <fstream> 
#include <cmath> 
#include <string> 
#include <sstream> 
using std::cout; 
using std::string; 
int main(){ 
    string nmbr; 
    { 
     std::ifstream in("ech.in"); 
     in >> nmbr; 
    } 
    short int size = nmbr.size(); 
    enum Equality{ 
     uneven, even, equal 
    }; 
    Equality eq = uneven; 
    int amount; 
    { 
     short int evn = 0; 
     short int unevn = 0; 
     for(int x = 0;x < size;x++){ 
      if(eq == even){ 
       evn += (nmbr[x] - '0'); 
       eq = uneven; 
      }else{ 
       unevn += (nmbr[x] - '0'); 
       eq = even; 
      } 
     } 
     amount = evn - unevn; 
     if(amount < 0){ 
      amount = amount * -1; 
     } 
     if(evn == unevn){ 
      eq = equal; 
     }else if(evn > unevn){ 
      eq = uneven; 
     }else{ 
      eq = even; 
     } 
    } 
    if(eq == equal){ 
     int i; 
     for(i = size - 1;true;i--){ 
      if(i < 0){ 
       string one = "1"; 
       nmbr = one.append(nmbr); 
       break; 
      } 
      if(nmbr[i] != '9'){ 
       nmbr[i]++; 
       break; 
      }else{ 
       nmbr[i] = '0'; 
      } 
     } 
     int sum = 0; 
     int sum1 = 0; 
     for(int x = size - 1;x >= 0;x -= 2){ 
      sum += (nmbr[x] - '0'); 
     } 
     for(int x = size - 2;x >= 0;x -= 2){ 
      sum1 += (nmbr[x] - '0'); 
     } 
     bool diff = true; 
     int diff1 = sum - sum1; 
     if(diff1 < 0){ 
      diff1 *= -1; 
      diff = false; 
     } 
     nmbr.append(", __last"); 
     if(diff1 == 0){ 
      goto output; 
     }else{ 
      i = size - 1 - diff; 
      for(;true;i -= 2){ 
       cout<<nmbr; 
       if(i == -1){ 
        std::stringstream ss; 
        ss << diff1 << nmbr; 
        nmbr = ss.str(); 
       }else{ 
        std::stringstream ss; 
        ss << diff1 * 10; 
        ss << nmbr; 
        nmbr = ss.str(); 
       } 
       int add = 9 - (nmbr[i] - '0'); 
       if(add > diff1){ 
        diff1 -= add; 
        nmbr[i] = '9'; 
       }else{ 
        nmbr[i] = std::to_string((nmbr[i] - '0') + diff1)[0]; 
        break; 
       } 
      } 
     } 
    }else{ 
     int i; 
     { 
      bool b = (nmbr.size() % 2) == 0; 
      if(eq == uneven){ 
       if(b) 
        i = nmbr.size() - 2; 
       else 
        i = nmbr.size() - 1; 
      }else{ 
       if(b) 
        i = nmbr.size() - 1; 
       else 
        i = nmbr.size() - 2; 
      } 
     } 
     for(;true;i -= 2){ 
      if(i < 0){ 
       for(int pow = 0;true;pow += 2){ 
        if(amount > 9){ 
         amount -= 9; 
         nmbr = std::to_string(9 * std::pow(1, pow)) + nmbr; 
        }else{ 
         nmbr = std::to_string(amount * std::pow(1, pow)); 
         break; 
        } 
       } 
       break; 
      } 
      int add = 9 - (nmbr[i] - '0'); 
      if(add > amount){ 
       amount -= add; 
       nmbr[i] = '9'; 
      }else{ 
       nmbr[i] = std::to_string(amount + (nmbr[i] - '0'))[0]; 
       break; 
      } 
     } 
    } 
    output: std::ofstream out("ech.out"); 
    out << nmbr; 
    return 0; 
} 
+3

Où est le code? – user6556709

+0

Ce que vous nous demandez n'est pas clair, alors je dis simplement oui. – DuKes0mE

+0

@ user6556709 Désolé, j'ai oublié ça, je vais télécharger le maintenant. – theo2003

Répondre

0

Je suis désolé si la question est difficile à comprendre. J'ai eu plusieurs problèmes, tous corrigés.

  1. Corruption de mémoire: J'utilisais une variable pour stocker la taille de la chaîne. La chaîne contenait des numéros qui lui étaient ajoutés, changeant sa taille. Remplacé par un appel à std :: string.size().
  2. "__dernier" a été placé après la chaîne. Les restes du débogage. Je vérifiais et quel point du programme la chaîne était corrompue et utilisée aléatoirement (générée automatiquement par éclipse lors de l'utilisation d'une fonction de manipulation de chaînes). Je l'ai juste enlevé. Problèmes mathématiques: En raison de la nécessité d'accéder en temps réel aux caractères d'un nombre, j'ai utilisé une chaîne et une boucle qui simulait l'addition de 1 à un nombre (si un chiffre était de 9, passer à 0, sinon ajouter 1). La condition pour la boucle était i >= 0 au lieu de i >= -1 empêchant l'instruction if qui traitait des index négatifs d'être atteints.
  3. Même PLUS Corruption: une instruction if incorrecte qui était un code mort. Au lieu de traiter les index négatifs, il a permis au code d'utiliser un index négatif lors de la manipulation des chaînes, ce qui corrompt la chaîne en changeant ses données internes. L'instruction if a été créée après la tentative de suppression de certaines boucles dont la condition est true et les instructions break à l'intérieur.

Je suis désolé pour le mauvais formatage de la question. Merci à UnholySheep d'avoir signalé la possibilité d'écraser la mémoire (je ne me suis pas rendu compte que vous faisiez référence à des index négatifs aussi).

-2

Avec des modifications mineures du code actuellement affiché, nous espérons que cela fonctionnera:

#include <iostream> 
#include <fstream> 
#include <cmath> 
#include <string> 
#include <sstream> 
using std::cout; 
using std::string; 
int main(){ 
    string nmbr; 
    { 
     std::ifstream in("ech.in"); 
     in >> nmbr; 
    } 
    enum Equality{ 
     uneven, even, equal 
    }; 
    Equality eq = uneven; 
    int amount; 
    { 
     short int evn = 0; 
     short int unevn = 0; 
     for(unsigned int x = 0;x < nmbr.size();x++){ 
      if(eq == even){ 
       evn += (nmbr[x] - '0'); 
       eq = uneven; 
      }else{ 
       unevn += (nmbr[x] - '0'); 
       eq = even; 
      } 
     } 
     amount = evn - unevn; 
     if(amount < 0){ 
      amount = amount * -1; 
     } 
     if(evn == unevn){ 
      eq = equal; 
     }else if(evn > unevn){ 
      eq = uneven; 
     }else{ 
      eq = even; 
     } 
    } 
    if(eq == equal){ 
     int i; 
     for(i = nmbr.size() - 1;i >= 0;i--){ // <-- changes here as I suggested in a deleted comment because I seen you tried it 
      // <-- some deletion here... 
      if(nmbr[i] != '9'){ 
       nmbr[i] = std::to_string((nmbr[i] - '0') + 1)[0]; 
       break; 
      }else{ 
       nmbr[i] = '0'; 
      } 
     } 
     nmbr = "1" + nmbr; // <-- and changes here 
     int sum = 0; 
     int sum1 = 0; 
     for(int x = nmbr.size() - 1;x >= 0;x -= 2){ 
      sum += (nmbr[x] - '0'); 
     } 
     for(int x = nmbr.size() - 2;x >= 0;x -= 2){ 
      sum1 += (nmbr[x] - '0'); 
     } 
     bool diff = true; 
     int diff1 = sum - sum1; 
     if(diff1 < 0){ 
      diff1 *= -1; 
      diff = false; 
     } 
     if(diff1 == 0){ 
      goto output; 
     }else{ 
      i = nmbr.size() - 1; 
      if(diff)i--; 
      for(;i >= -2;i -= 2){ 
       if(i == -1){ 
        std::stringstream ss; 
        ss << diff1 << nmbr; 
        nmbr = ss.str(); 
       }else if(i == -2){ 
        std::stringstream ss; 
        ss << diff1 * 10; 
        ss << nmbr; 
        nmbr = ss.str(); 
       } 
       int add = 9 - (nmbr[i] - '0'); 
       if(add < diff1){ 
        diff1 -= add; 
        nmbr[i] = '9'; 
       }else{ 
        nmbr[i] = std::to_string((nmbr[i] - '0') + diff1)[0]; 
        break; 
       } 
      } 
     } 
    }else{ 
     int i; 
     { 
      bool b = (nmbr.size() % 2) == 0; 
      if(eq == uneven){ 
       if(b) 
        i = nmbr.size() - 2; 
       else 
        i = nmbr.size() - 1; 
      }else{ 
       if(b) 
        i = nmbr.size() - 1; 
       else 
        i = nmbr.size() - 2; 
      } 
     } 
     for(;i >= -1;i -= 2){ 
      if(i < 0){ 
       for(int pow = 0;true;pow += 2){ 
        if(amount > 9){ 
         amount -= 9; 
         nmbr = std::to_string(9 * std::pow(1, pow)) + nmbr; 
        }else{ 
         nmbr = std::to_string(amount * std::pow(1, pow)); 
         break; 
        } 
       } 
       break; 
      } 
      int add = 9 - (nmbr[i] - '0'); 
      if(add > amount){ 
       amount -= add; 
       nmbr[i] = '9'; 
      }else{ 
       nmbr[i] = std::to_string(amount + (nmbr[i] - '0'))[0]; 
       break; 
      } 
     } 
    } 
    output: std::ofstream out("ech.out"); 
    out << nmbr; 
    return 0; 
} 

EDITé DE: (ceci a nswer n'applique plus autant de changements dans le code de la question)

Vous manipulez votre chaîne trop loin, lorsque vous accédez à ses caractères uniques, le dernier caractère doit toujours être '\ 0' afin d'utiliser des opérations et des fonctions qui compter sur ce fait (comme l'imprimer).

Essayez de vous assurer en écrivant

nmbr[size - 1] = '\0'; 

ou quelque chose de similaire, avant l'impression.

+0

Je ne fais que l'imprimer pour voir s'il est corrompu. J'utilise 'cout' de toute façon. – theo2003

+0

Je n'utilise que des fonctions C++. – theo2003