2011-10-02 6 views
0

Je veux construire un programme qui somme de grands entiers dans C. Donc je suis prêt avec le code. Le programme de compilation réussit avec mingw et le compilateur Visual C++. Mais j'ai un problème avec la partie run. La chose étrange est que quand je débogue le programme dans Visual Studio il n'y a aucun problème mais quand je l'exécute mon Windows montre que le programme cesse de fonctionner. Voici le code:C fonctions str et malloc

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <math.h> 
#include <ctype.h> 
#include "sum.h" 

int isNumber(char* number) 
{ 
    int lenght = strlen(number); 
    int i,result = 0; 
    for (i = 0 ; i < lenght ; i++) 
    { 
     if (isdigit(*number++)) 
     { 
      result = 1; 
     } 
     else 
     { 
      result = 0; 
      break; 
     } 
    } 
    return result; 
} 
int cti(char ch) 
{ 
    return ch - '0'; 
} 
char* addZeros(char* number,int lenght) 
{ 
    int num_lenght = strlen(number),size = abs(lenght - num_lenght),i; 
    char* zeros = (char*)malloc(size); 

    strcpy(zeros,""); 
    zeros[size - 1] = '\0'; 
    for (i = 0 ; i < abs(lenght - num_lenght) ; i++) 
    { 
     strcpy(&zeros[i],"0"); 
    } 
    strncat(zeros,number,size); 
    number = (char*)malloc(sizeof(char)*size); 
    strncpy(number,zeros,size); 
    return number; 
} 
char* sum(char* numberOne,char* numberTwo) 
{ 
    if (numberOne == NULL || numberTwo == NULL) 
     return NULL; 
    if (!isNumber(numberOne) || !isNumber(numberTwo)) 
     return NULL; 

    int CF = 0; 
    int lenghtOne = strlen(numberOne),lenghtTwo = strlen(numberTwo); 
    if (lenghtOne == 0 || lenghtTwo == 0) 
     return lenghtOne == 0 ? numberTwo : numberOne; 
    int max = lenghtOne > lenghtTwo? lenghtOne : lenghtTwo,index; 
    char* result = (char*)malloc(max); 
    int res = 0; 
    result[max] = '\0'; 
    if (lenghtOne > lenghtTwo) numberTwo=addZeros(numberTwo,strlen(numberOne)); 
    else if (lenghtOne < lenghtTwo) numberOne = addZeros(numberOne,strlen(numberTwo)); 
    for (index = max - 1 ; index >=0 ; index--) 
    { 
     res = cti(numberOne[index]) + cti(numberTwo[index]); 
     if (((res%10) + CF) > 9) 
     { 
      int num = ((res%10) + CF); 

      result[index] = (char)((int)'0'+num%10); 
      CF = num/10; 
     } 
     else 
     { 
      result[index] = (char)((int)'0'+((res%10) + CF)); 
      CF = res/10; 
     } 
    } 
    return result; 
} 
int main(int argc, char *argv[]) 
{ 
    char* num = "12345678"; 
    char* num2= "2341"; 
    char* result = sum(num,num2); 
    printf("%s\n",result); 
    return 0; 
} 

Je pense que le problème est quelque part dans les pointeurs, mais je ne suis pas absolument sûr à ce sujet. Quelqu'un peut-il m'aider?

+3

Alors quel problème voyez-vous, quand vous la voyez? – johannes

Répondre

2

La quantité de mémoire allouée n'est pas suffisante. Il n'inclut pas d'espace pour le caractère nul terminant la chaîne et ne prend pas en compte les changements dans la longueur du résultat pour des sommes telles que "9" + "1". Vous écrivez ensuite le caractère de fin nul après la fin du tableau.

Vous devez malloc avec la longueur comme ceci:

char* result = (char*)malloc(max + 2); 
+0

Vous aviez raison mais la taille de l'allocation doit être max + 1 –

+0

@Jordan Borisov: Il doit être max + 2. Vous avez besoin de +1 pour le terminateur nul et un autre +1 pour les cas où la longueur du résultat est supérieure à la longueur des cordes. Pour l'exemple que j'ai donné dans ma réponse, "10" aura besoin d'espace pour 3 caractères alors que les deux chaînes d'entrée ont une longueur de 1. Par conséquent, il doit être max + 2. – tinman

1
result[max] = '\0'; 

Ceci est incorrect car vous avez uniquement alloué des caractères max pour le résultat. Je n'ai pas étudié la logique en détail mais l'allocation de max + 1 caractères permettrait de résoudre ce problème particulier.