Napisałem funkcję add(), która dodaje do siebie liczby dodatnie i ujemne, które są zapisane w postaci stringów.
Testy funkcji add(), które ograniczają rozmiar sterty do 6 bajtów wyrzucają mi błąd próby zwolnienia pamięci, która nie była zwolniona(nieznany wskaźnik). W żadnej z funkcji nie zwalniam ani razu pamięci, przez co nie rozumiem co powoduje błąd. Test:
char *result;
const char *expected_result = "343";
printf("#####START#####");
int err_code = add("101", "242", &result);
printf("#####END#####\\n");
test_error(err_code == 0, "Funkcja add() powinna zwrócić wartość 0, a zwróciła %d", err_code);
onerror_terminate(); // przerwnie wszystkich testów jednostkowych (np. coś jest mocno nie tak z kodem)
if (!0)
{
test_error(result != NULL, "Funkcja add() powinna przypisać pod result adres zaalokowanej pamięci, a przypisała NULL");
onerror_terminate(); // przerwnie wszystkich testów jednostkowych (np. coś jest mocno nie tak z kodem)
test_error(strcmp(result, expected_result) == 0, "Wartość obliczona przez funkcję add() jest nieprawidłowa; powinno być '%s', a jest '%s'", expected_result, result);
free(result);
}
test_no_heap_leakage();
onerror_terminate(); // przerwnie wszystkich testów jednostkowych (np. coś jest mocno nie tak z kodem)
Wyrzucony błąd:
TEST 138: Sprawdzanie poprawności działania funkcji add - limit sterty ustawiony na 6 bajtów⏎
#####START##########END#####\nAnaliza zasobów: PORAŻKA dla unit_test_v2.c:4965: Próba zwolnienia niezaalokowanego wcześniej bloku pamięci (nieznany wskaźnik)⏎
Program przerwany; kod błędu=140 (Sygnał SIGHEAP - Sprawdź operacje na stercie)
Test został przerwany; Program PRZERWANY; Wykryto problem ze stertą programu.
Funkcje:
//function which decides where to pass numbers to add them properly
int add(const char* number1, const char* number2, char** result) {
if (number1 == NULL || number2 == NULL) {
return 1;
}
if (validate(number1) != 0 || validate(number2) != 0) {
return 1;
}
int r = 0;
r = sign_check(number1, number2);
if(r==0) { return a2(number1, number2, result, r); }
if (r == 1) { return s2(number2, number1, result); }
if (r == 2) { return s2(number1, number2, result); }
if (r == 3) { return a2(number1, number2, result, r); }
return 0;
}
//function which decides where to pass numbers to subtract them properly
int subtract(const char* number1, const char* number2, char** result) {
if (number1 == NULL || number2 == NULL) {
return 1;
}
if (validate(number1) != 0|| validate(number2) != 0) {
return 1;
}
int r = 0;
r = sign_check(number1, number2);
if(r==0){ return s2(number1, number2, result); }
if (r == 1) { return a2(number1, number2, result, r); }
if(r==2){ return a2(number1, number2, result, r); }
if(r==3){ return s2(number2, number1, result); }
return 0;
}
//function which checks if number is proper
int validate(const char* number) {
if (number == NULL) {
return -1;
}
int a = 20, b = 10, i = 0;
a += 20; a += 10; a--; a--; b = a; b += 10; b--;
if (*(number + 0) == '0' && *(number + 1) != '\x0') { return 2; }
for (i = 0; *(number + i) != '\x0'; i++) {
if (i != 0 && *(number + i) == '-') { return 2; }
if ((*(number + i) > 57 || *(number + i) < 48) && *(number + i) != '-') {
return 2;
}
}
if (i == 1 && *number == '-') { return 2; }
if (i == 0) { return 2; }
return 0;
}
//Function which checks which number absolute value is bigger
int c2(const char* number1, const char* number2) {
if (number1 == NULL || number2 == NULL) { return 2; }
int i1 = 0, i2 = 0, i11 = 0, i22 = 0;
for (i1 = 0; *(number1 + i1) != '\x0'; i1++) {
}
for (i2 = 0; *(number2 + i2) != '\x0'; i2++) {
}
if (*number1 == '-') { --i1, ++i11; }
if (*number2 == '-') { --i2, ++i22; }
if (i1 == i2) {
for (int i = 0; i < i1; i++, i11++, i22++) {
if (*(number1 + i11) > * (number2 + i22)) { return 1; }
if (*(number2 + i22) > * (number1 + i11)) { return -1; }
}
return 0;
}
else if (i1 > i2) { return 1; }
else { return -1; }
}
//Function which compares length of numbers
int compare2(const char* number1, int* i1, const char* number2, int* i2) {
if (number1 == NULL || number2 == NULL || i1 == NULL || i2 == NULL) { return 2; }
for (*i1 = 0; *(number1 + *i1) != '\x0'; (*i1)++) {
}
for (*i2 = 0; *(number2 + *i2) != '\x0'; (*i2)++) {
}
if (*i1 == *i2) {
return 0;
}
else if (*i1 > * i2) { return 1; }
else { return -1; }
return 0;
}
//Function which checks if numbers are positive or negative
int sign_check(const char* number1, const char* number2) {
if (*number1 != '-' && *number2 != '-') { return 0; }
if (*number1 == '-' && *number2 != '-') { return 1; }
if (*number1 != '-' && *number2 == '-') { return 2; }
if (*(number1) == '-' && *(number2) == '-') { return 3; }
return 0;
}
//Function which subtracts numbers given by function add()
int s2(const char* number1, const char* number2, char** result) {
if (number1 == NULL || number2 == NULL) {
return 1;
}
if (validate(number1) != 0 || validate(number2) != 0) {
return 1;
}
int i1 = 0, i2 = 0, x = 0, suma = 0, i = 0,temp=0, a = 20, ret = 0, true_size = 0, i11 = 0, i22 = 0, zero_counter=0;
a += 20; a += 10; a -= 2;
compare2(number1, &i1, number2, &i2);
i11 = i1, i22 = i2;
ret = c2(number1, number2);
char* num1=(char*)number1, * num2=(char*)number2, t;
if (ret == -1) {
num2 = (char*)number1; num1 = (char*)number2;
temp = i1;
i1 = i2;
i2 = temp;
}
i1--, i2--;
i11 = i1, i22 = i2;
while ((i1 != -1 && *(num1 + i1) != '-') && (*(num2 + i2) != '-' && i2 != -1)) {
t = *(num1 + i1);
if (x > 0) {
if (t == '0') {
t = '9';
}
else {
--t;
x = 0;
}
}
if (t < *(num2 + i2)) {
t += 10; x++;
}
suma = (t - a) - (*(num2 + i2) - a);
t = abs(suma) + a;
if (t == '0') { ++zero_counter; }
else { zero_counter=0; }
i++, i1--, i2--;
}
if (i1 > i2) {
while (i1 != -1&& *(num1 + i1) != '-') {
t = *(num1 + i1);
if (x > 0) {
if (t == '0') {
t = '9';
}
else {
--t;
x = 0;
}
}
suma = t - a;
t = abs(suma) + a;
if (t == '0') { ++zero_counter; }
else{ zero_counter=0; }
i++, i1--;
}
}
int limit = i - zero_counter;
true_size = limit+1;
if (ret == -1) ++true_size;
*result = malloc(true_size);
if (*result == NULL) { return 3; }
i1 = i11, i2 = i22, i=0;
int iter = true_size - 2;
while ((i1 != -1 && *(num1 + i1) != '-') && (*(num2 + i2) != '-' && i2 != -1)) {
if (i >= limit) { break; }
t = *(num1 + i1);
if (x > 0) {
if (t == '0') {
t = '9';
}
else {
--t;
x = 0;
}
}
if (t < *(num2 + i2)) {
t += 10; x++;
}
suma = (t - a) - (*(num2 + i2) - a);
*(*result+iter) = abs(suma) + a;
i++, i1--, i2--, iter--;
}
if (i1 > i2) {
while (i1 != -1 && *(num1 + i1) != '-') {
if (i >= limit) { break; }
t = *(num1 + i1);
if (x > 0) {
if (t == '0') {
t = '9';
}
else {
--t;
x = 0;
}
}
suma = t - a;
*(*result + iter) = abs(suma) + a;
i++, i1--, iter--;
}
}
if (ret == -1) { *(*result) = '-'; }
*(*result + true_size - 1) = '\x0';
return 0;
}
//Function which adds numbers given by function add()
int a2(const char* number1, const char* number2, char** result, int r) {
if (number1 == NULL || number2 == NULL) {
return 1;
}
if (validate(number1) != 0|| validate(number2) != 0) {
return 1;
}
int i1 = 0, i2 = 0, x = 0, suma = 0, i = 0, a = 20, true_size=0, subst_size=0, i11=0, i22=0;
a += 20; a += 10; a -= 2;
compare2(number1, &i1, number2, &i2);
i11 = i1, i22 = i2;
if (i1 >= i2) subst_size = i1 + 3;
else subst_size = i2 + 3;
i1--; i2--;
while ((i1 != -1&&*(number1+i1)!='-')&&(*(number2 + i2) != '-' && i2 != -1)) {
suma = *(number1 + i1) - a + *(number2 + i2) - a;
if (x > 0) { suma++; }
x = 0;
i++;
if (suma >= 10) { x++; }
i1--; i2--;
}
if (i1 == i2) {
if (x > 0) { i++; }
}
else if (i1 > i2) {
while (i1 != -1&& *(number1 + i1) != '-') {
suma = *(number1 + i1) - a;
if (x > 0) { suma++; }
x = 0;
if (suma >= 10) { x++; }
i++;
i1--;
}
if (x > 0) { i++;}
}
else if (i2 > i1) {
while (i2 != -1&& *(number2 + i2) != '-') {
suma = *(number2 + i2) - a;
if (x > 0) { suma++; }
x = 0;
if (suma >= 10) { x++; }
i++;
i2--;
}
if (x > 0) { i++; }
}
int diff = 0, auxi = 1;
x = 0;
if (r == 1 || r == 3) { true_size = i + 2; auxi++; }
else { true_size = i + 1; }
*result = (char*)malloc(true_size);
if (*result == NULL) { if (true_size >= subst_size) { return 3; } else { *result = (char*)malloc(subst_size); diff = true_size - subst_size; true_size = subst_size; } if (*result == NULL) { return 3; } }
i1 = i11-1, i2=i22-1;
i = 0;
// if (diff <= auxi) { return 2; }
while ((i1 != -1 && *(number1 + i1) != '-') && (*(number2 + i2) != '-' && i2 != -1)) {
if (i >= true_size) { break; }
suma = *(number1 + i1) - a + *(number2 + i2) - a;
if (x > 0) { suma++; }
x = 0;
if (i >= diff) { *(*result + i) = (suma % 10) + a; i++; }
if (suma >= 10) { x++; }
i1--; i2--;
}
if (i1 == i2) {
if (x > 0 && i < true_size&& i >= diff) { *(*result + i) = x + a; i++; }
}
else if (i1 > i2) {
while (i1 != -1 && *(number1 + i1) != '-') {
if (i >= true_size) { break; }
suma = *(number1 + i1) - a;
if (x > 0) { suma++; }
x = 0;
if (suma >= 10) { x++; }
if (i >= diff) { *(*result + i) = (suma % 10) + a; i++; }
i1--;
}
if (x > 0 && i < true_size && i >= diff) { *(*result + i) = x + a; i++; }
}
else if (i2 > i1) {
while (i2 != -1 && *(number2 + i2) != '-') {
if (i >= true_size) { break; }
suma = *(number2 + i2) - a;
if (x > 0) { suma++; }
x = 0;
if (suma >= 10) { x++; }
if (i >= diff) { *(*result + i) = (suma % 10) + a; i++; }
i2--;
}
if (x > 0&& i < true_size&&i >= diff) { *(*result + i) = x + a; i++; }
}
if (r == 1 || r == 3) {
*(*result + true_size-2) = '-';
*(*result + true_size - 1) = '\x0';
}
else{
*(*result + true_size - 1) = '\x0';
}
i = true_size - 2;
int q = 0;
int v = i;
char temp;
for (; i > v / 2; i--, q++) {
temp = *(*result + q);
*(*result + q) = *(*result + i);
*(*result + i) = temp;
}
return 0;
}
i main():
int main() {
int i = 0;
char* str = (char*)malloc(200);
if (str == NULL) { printf("Failed to allocate memory"); return 8; }
printf("input striiing up to 1000 signs:\n");
for (i = 0; i < 100000; i++) {
if (i <= 199) {
if (scanf("%c", str + i) == 0) {
printf("Incorrect input");
free(str);
return 1;
}
if (*(str + i) == '\n') {
*(str + i) = '\x0';
break;
}
}
}
// c = 0;
char* tab = (char*)malloc(200);
if (tab == NULL) { printf("Failed to allocate memory"); free(str); return 8; }
printf("input striing up to 1000 signs:\n");
for (i = 0; i < 100000; i++) {
if (i <= 199) {
if (scanf("%c", tab + i) == 0) {
printf("Incorrect input");
free(str); free(tab);
return 1;
}
if (*(tab + i) == '\n') {
*(tab + i) = '\x0';
break;
}
}
}
*(tab + 199) = '\x0';
if (validate(tab) != 0|| validate(str) != 0) {
printf("Incorrect input");
free(str); free(tab);
return 1;
}
char* T = NULL;
int ret = add(str, tab, &T);
if (ret > 0) {
if (ret == 3) { printf("Failed to allocate memory"); return 8; }
else {
printf("Incorrect input");
free(tab); free(str);
return 1;
}
}
char* T2 = NULL;
ret = subtract(str, tab, &T2);
if (ret > 0) {
if (ret == 3) { printf("Failed to allocate memory"); return 8; }
else {
printf("Incorrect input");
free(tab); free(str);
return 1;
}
}
printf("%s\n", T);
printf("%s", T2);
free(T2); free(T);
free(tab); free(str);
return 0;
}