0

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))

Stefano Carletto
  • 33
  • 1
  • 1
  • 6
  • 5
    `sizeof(*stringa) / sizeof(*stringa[0])` is the size of a pointer, or 8 on your system, divided by the size of a char which is always 1. You can't determine the size of an allocated block of memory that way, only the size of an array in the scope where it is declared. If you use `malloc/calloc/realloc` you need to keep track of the size yourself if you need it. – Retired Ninja Jun 21 '23 at 03:54
  • 1
    @Stefano Carletto, `"%d"` is the wrong specifier to print a `size_t` type. Use `printf("%zu\n", sizeof(*stringa) / sizeof(*stringa[0]));`. This will not solve the "8 is the number it prints every time" issue, yet is solves others. – chux - Reinstate Monica Jun 21 '23 at 06:09

1 Answers1

4

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.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • The function call is : `char *stringa = (char*) malloc(sizeof(char)), *reverse = (char*) malloc(sizeof(char));` `int iStringa;` `inputStringaAndCreateReverse(&stringa, &reverse, &iStringa);` So that the starting size of the pointer is 1, and with time it grows larger and larger. I changed `reverse = ...` into `*reverse = ...` I missed that lol. Btw `i` is supposed to start from 0 and, after `*stringa[i++] = inputChar` to be 1, 2 ,3... The problem is that it is stopping suddently from every input it is given and I cant figure out why... – Stefano Carletto Jun 21 '23 at 21:50
  • Okay in it's correct to start from `size = 1`. I find it strange but you can decide whatever you want. It's your program :-) But I would start from 0 and do a `malloc` in the function before the first assignment. – Support Ukraine Jun 22 '23 at 04:46
  • @StefanoCarletto Did you look into the expression `*stringa[i++]` ? As I said it's not doing what you think. To get it right, you need to write `(*stringa)[i++]` or alternatively `stringa[0][i++]`. That said, I wouldn't use `stringa` directly in the function. Double pointers are confusing for many programmers. I would use a local single pointer inside the function. Initialize it using `*stringa` and assign back to `*stringa` just before return. That will make your code much simpler... – Support Ukraine Jun 22 '23 at 04:50