Функция добавления большого числа вылетает из программы
Я написал функцию добавления для очень больших чисел, и когда она вызывается, программа вылетает. Я предполагаю, что это связано с переноской. Вот код:
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 ответ
У вашей программы так много проблем!
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);
}
}