Search code examples
cdynamic-memory-allocation

Unexpected behavior in array input


This function is supposed to read and expand my array (stringa) until the user hits enter, then expands also reverse to the same size of stringa.

But after 3 letters the program just stops

void inputStringaAndCreateReverse(char* *stringa, char* *reverse, int* iStringa) {
    int inputChar, i = 0, size = 1;
    bool notEnter = true;
    printf("Insert the string: ");
    while (notEnter) {
        if ((inputChar = getche()) != '\r') {
            *stringa[i] = inputChar;
            i++;
            *stringa = realloc(*stringa, (++size) * sizeof(char));
        } else if (size != 1) {
            notEnter = false;
            system("CLS");
        } else {
            printf("\n");
        }
    }
    *stringa[i] = '\0';
    *iStringa = strlen(*stringa) - 1;
    *reverse = realloc(*reverse, (*iStringa + 1) * sizeof(char));
}

These are the results of a test (I wanted to write hello)
hell

stringa and reverse are allocated in the main as
stringa = (char*) malloc(sizeof(char))


Solution

  • It seems you expect printf("%d\n", sizeof(*stringa) / sizeof(*stringa[0])); to print the number of characters (re)allocated to *stringa.

    If so then the answer is: Your expectations are wrong.

    Let's take a step backwards.

    For arrays it is true that code like

    sizeof(array) / sizeof(array[0])
    

    will give the number of array elements.

    For instance:

    int array[] = {1, 10, 100, 1000};
    size_t elements = sizeof(array) / sizeof(array[0]);
    

    will assign the value 4 to elements.

    But that is not what you are doing.

    Your stringa is not an array. Your stringa variable has the type pointer to a pointer to a char.

    Consequently *stringa has the type pointer to a char.

    So sizeof(*stringa) is the same as sizeof(char*)

    stringa[0] is also a pointer to char and consequently *stringa[0] is a char. That means that sizeof(*stringa[0]) is the same as sizeof(char).

    Now we can rewrite

    sizeof(*stringa) / sizeof(*stringa[0])
    

    to be

    sizeof(char*) / sizeof(char)
    

    Since sizeof(char) is always 1 we can even write it as just

    sizeof(char*)
    

    The size of a pointer is a fixed number. It does not change depending on the amount of memory that it points to. On most 64-bit systems (if not all) the size of a pointer is 8. That's why your print statement always show 8.

    BTW:

    *stringa[i++] is not doing what you expect. Check operator precedence.

    reverse = ... should probably be *reverse = ...

    OT:

    The code starts with size = 1. You haven't shown us how you call the function so it may be correct/intended but it seems rather strange. Do you really expect the caller to provide a pointer to a pointer to a char that already points to exactly one dynamic allocated char? To me that's a very strange function API.