1

I am working on a program and I successfully isolated the non-working part, but I can't figure out why this does not work. The realloc inside the function shold reallocate the array elements but sometimes the addresses are the same and sometimes they are just 0, which causes errors inside the code and crashes

int main() {
    char *string = (char*) malloc(sizeof(char));
    resizeString(&string);
    free(string)
    return 0;
}

void resizeString(char* *string) {
    int q;
    *string = realloc(*string, 5 * sizeof(char));
    for (q = 0; q < 5; q++) {
        printf("0x%p ", &*string[q]);
    }
    printf("\n");
}

this is the result of the printf inside the for loop

Barmar
  • 741,623
  • 53
  • 500
  • 612
Stefano Carletto
  • 33
  • 1
  • 1
  • 6
  • 3
    Please post code, data, **and results** as text, not screenshots ([how to format code in posts](https://stackoverflow.com/help/formatting)). [Why should I not upload images of code/data/errors?](https://meta.stackoverflow.com/questions/285551/why-should-i-not-upload-images-of-code-data-errors) http://idownvotedbecau.se/imageofcode – Barmar Jun 22 '23 at 00:42
  • No clue what the order of operations is for `&*string[q]`. If you want to print the address of each character try `printf("%p ", (void*)((*string) + q));` – yano Jun 22 '23 at 00:48
  • See the documentation. Sometimes it returns the same value, if the memory block could be expanded *in situ,* and it returns 0 if out of memory. You need to test for that case, and you aren't, so when it returns 0 you are getting a SIGSEGV. – user207421 Jun 22 '23 at 00:50
  • just a couple other things, 1) be sure to [`realloc` properly with a temp ptr](https://stackoverflow.com/questions/21006707/proper-usage-of-realloc) to avoid the possibility of a memory leak, and 2) understand that `realloc` does not _add_ to the previously allocated space, it only allocates the space specified. So each time you call `resizeString` it won't allocate 5, 10, 15, etc bytes each call, just 5 each time. – yano Jun 22 '23 at 04:34

2 Answers2

3

You need to add parentheses to print the addresses of the array elements properly.

        printf("%p ", &(*string)[q]);

This correctly prints consecutive addresses:

0x6000013dc040 0x6000013dc041 0x6000013dc042 0x6000013dc043 0x6000013dc044 

This has nothing to do with realloc(), you'd have the same problem if you allocated 5 characters originally.

There's also no need to write 0x in the format string; most C libraries show that prefix automatically as part of %p format.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • So this is the problem in the main code: I did not write `(*string)[q]` but, instead, `*string[q]` which I assume resulted in unexpected behaviour cause of operator precedence, I did not think of that in this way... thank you very much now my code is running without problems!!! – Stefano Carletto Jun 22 '23 at 01:46
1

The realloc() call in your code is basically working, but there are two other problems:

  1. Your initial one-char allocation is never initialized (so it's indeterminate what character will be in it before or after the realloc() call)

  2. Your code to print out the characters in the post-realloc() array is wrong (it's trying to print out pointers, not characters, which doesn't make sense).

Here's an updated version of the code that does what you'd expect (note that I've initialized the original char to X aka 0x58 in main() so that we can verify that it is still set to that value after the realloc occurs)

#include <string.h>
#include <stdio.h>
#include <stdlib.h>

void resizeString(char* *string) {
    int q;

    char * s = (char *) realloc(*string, 5 * sizeof(char));
    for (q = 0; q < 5; q++) {
        printf("0x%x ", s[q]);
    }
    printf("\n");

    *string = s;  // update calling code's pointer to the new buffer location
}

int main() {
   char *string = (char*) malloc(sizeof(char));
   *string = 'X';

   resizeString(&string);
   free(string);
   return 0;
}

... running the above gives this output:

0x58 0x0 0x0 0x0 0x0 
Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234