大数字添加功能崩溃程序

时间:2015-04-12 21:48:18

标签: c bignum

我为非常大的数字编写了一个添加函数,当它被调用时,程序崩溃了。我假设它与携带有关。这是代码:

char * bigadd(char a[], char b[]){

int i, temp;
char useadd[MAX];
char usea = strrev(a);
char useb = strrev(b);
char ret[strlen(useadd)];
char *pa, *pb, *padd;

padd = &useadd;
pa = &usea;
pb = &useb;

while(*pa != '\0' && *pb != '\0'){

    if(atoi(*pa) + atoi(*pb) + temp > 9){

        if(temp + atoi(*pa) + atoi(*pb) < 20){
            temp = 1;
            *padd = atoi(*pa) + atoi(*pb) - 10;
        }
        else{
            temp = 2;
            *padd = atoi(*pa) + atoi(*pb) - 20;
        }
    }
    else{
        *padd = atoi(*pa) + atoi(*pb);
        temp = 0;
    }
    ++padd;
    ++pa;
    ++pb;

}

i = 0;
while(useadd[i] != '\0'){
    ret[i] = useadd[i];
    ++i;
}
return strrev(ret);
}

感谢所有帮助。如果这最终成为一个愚蠢的错误,我很抱歉。

1 个答案:

答案 0 :(得分:0)

你的程序有很多问题!

char * bigadd(char a[], char b[]){
   int i, temp;
   char useadd[MAX];  // MAX might not be large enough
   char usea = strrev(a); // should not modify argument a
                          // strrev() is not standard C undefined on my system
                          // if defined, it returns char*, not char
   char useb = strrev(b); // see above
   char ret[strlen(useadd)]; // useadd is uninitialized -> undefined behaviour
   char *pa, *pb, *padd;

   padd = &useadd; // & is incorrect, useadd is an array
   pa = &usea;     // same as above
   pb = &useb;     // idem
                   // forgot to initialize temp to 0
   while(*pa != '\0' && *pb != '\0'){
      if(atoi(*pa) + atoi(*pb) + temp > 9){ // atoi converts a string, not a char
         if(temp + atoi(*pa) + atoi(*pb) < 20){ // same... sum cannot exceed 19
            temp = 1;
            *padd = atoi(*pa) + atoi(*pb) - 10; // atoi...
         }
         else{ // never reached
            temp = 2;
            *padd = atoi(*pa) + atoi(*pb) - 20; // atoi...
         }
      }
      else{
         *padd = atoi(*pa) + atoi(*pb); // same atoi problem
         temp = 0;
      }
      ++padd;
      ++pa;
      ++pb;
   }
   // if a and b have a different size, loop fails to copy digits and propagate carry
   // if temp is not 0, you forget to add the leading '1'
   // trailing '\0' is not set

   i = 0;
   while(useadd[i] != '\0'){ // undefined behaviour, '\0' not set.
      ret[i] = useadd[i];
      ++i;
   }
   // forgot to set the final '\0'
   // why not use strcpy?
   return strrev(ret); // strrev not defined.
                       // if defined, returning ret, address of local array
}

这是一个完整的重写:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *bigadd(const char a[], const char b[]) {
    int ia = strlen(a);
    int ib = strlen(b);
    int size = 2 + (ia > ib ? ia : ib), ic = size - 1, temp = 0;
    char *res = malloc(size);

    if (res) {
        res[--ic] = '\0';
        while (ia + ib) {
            if (ia > 0) temp += a[--ia] - '0';
            if (ib > 0) temp += b[--ib] - '0';
            res[--ic] = '0' + temp % 10;
            temp /= 10;
        }
        if (temp) {
            memmove(res + 1, res, size - 1);
            *res = '1';
        }
    }
    return res;
}

int main(int argc, char *argv[]) {
    for (int i = 1; i + 1 < argc; i += 2) {
        char *res = bigadd(argv[i], argv[i+1]);
        printf("%s + %s = %s\n", argv[i], argv[i+1], res);
        free(res);
    }
}
相关问题