Search code examples
c++type-conversionmallocuser-inputdynamic-memory-allocation

Should i use 'malloc(0)' or 'free() and then set variable to NULL'? What's better?


I am currently writing a function that prohibits the user from entering unnecessary characters, and writes numbers to an array, and then converts from the array to int, then returns. I want to make a function based on a dynamic array. The algorithm is as follows: I enter a number, the array expands, erase the number, the array shrinks. The problem appears when the string is empty after erasure and waits for a number to be entered. How should I proceed in this case? Use malloc(0) or use free(), and then set the pointer equal to NULL?

Can I just set the pointer to NULL and thereby clear it? Probably, the answer is no I can't, because I think memory cells are still filled with data, but I want to hear more detailed answers.

Is my implementation of the idea bad?

At the beginning of the code, there is a comment, if the number exceeds the value 2147483647 then the algorithm behaves strangely, have any ideas why this is happening?

Sorry for the questions, but it is really driving me nuts. I searched the entire Internet and did not find any answers to my questions, even on StackOverflow and in the proposed duplicates.

long long int number_input(int limit)
{
    // Limit set the number of digits in the number

    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // I have no idea why is that happening 
    // 2.147.483.647 = 2147483647
    // 2.147.483.648 = -2147483648
    // -2.147.483.648 = -2147483648
    // -2.147.483.649 = -2147483647

    char c;             // current entered symbol   
    int length = 0;     // length of number (digit capacity, minus included), but index for digits is length - 1
    char* number_array_pointer = NULL;
    long long int number_array_integer = 0;
    int index;      // index for converting string to integer


    if ((number_array_pointer = (char*)realloc(number_array_pointer, sizeof(char) * length)) == NULL) {
        cout << "Fatal: failed to allocate " << sizeof(char) * length << " bytes.\n";
        abort();
    }

    for (;;) {
        c = _getch();
        if (c == 13 && length != 0) {       // Enter breaks down the loop
            if (number_array_pointer[0] == '-' && length < 2) {
                continue;
            }else {
                break;
            }
        }
        else if (c == '\b' && length != 0) {    // Backspace
            cout << "\b \b";
            length--;
            if (length == 0)
            {
                // malloc(0) vs free() then ' = NULL'
                if ((number_array_pointer = (char*)malloc(sizeof(char) * length)) == NULL) {
                    cout << "Fatal: failed to allocate " << sizeof(char) * length << " bytes.\n";
                    abort();
                }
            }       // We cannot realloc 0 bytes
            else if ((number_array_pointer = (char*)realloc(number_array_pointer, sizeof(char) * length)) == NULL) {
                cout << "Fatal: failed to reallocate " << sizeof(char) * length << " bytes.\n";
                abort();
            }
        }
        else if (c == 45 && length == 0) {      // Minus for negative number
            length++;
            if ((number_array_pointer = (char*)realloc(number_array_pointer, sizeof(char) * length)) == NULL) {
                cout << "Fatal: failed to reallocate " << sizeof(char) * length << " bytes.\n";
                abort();
            }
            number_array_pointer[length - 1] = c;
            cout << c;
        }
        else if (c > 47 && c < 58 && length < limit) {      //  Allow to enter only digits
            length++;
            if ((number_array_pointer = (char*)realloc(number_array_pointer, sizeof(char) * length)) == NULL) {
                cout << "Fatal: failed to reallocate " << sizeof(char) * length << " bytes.\n";
                abort();
            }
            number_array_pointer[length - 1] = c;
            cout << c;
        }
        else {
            continue;
        }
    }

    if (number_array_pointer[0] == '-') {
        index = 1;
    }
    else {
        index = 0;
    }

    for (index; index < length; index++)
    {
        number_array_integer *= 10;
        // get the actual digit from ascii code
        number_array_integer += (long long int)number_array_pointer[index] - 48;
    }

    if (number_array_pointer[0] == '-') {
        number_array_integer *= -1;
    }

    free(number_array_pointer);
    return number_array_integer;
}

Solution

  • Here's the answer to your second part as to why things go off-track if the number exceeds the value 2147483647

    #include <iostream>
    #include <limits>
    
    int main() {
      std::cout<<"The answer is "<<std::numeric_limits<int>::max();
    }
    

    Output:

    The answer is 2147483647.
    

    That's the maximum value of a 32-bit integer (the usual int on platforms is 32-bit).

    As to your first part, please use std::vector if there's no inhibition on using it! I'll let someone else answer that.