1

I am just writing a code that has to reallocate an array X of pointers to constant strings A,B,C (see scheme below):

 _______ _______ _______     ________     ________________ 
|char* A|char* B|char* C|...|char** X|...|char*** pref_arr|...
 """"""" """"""" """""""     """"""""     """""""""""""""" 
     __                             __
    |\______________________/      |\__________/

I have the array of A,B,C, pointer to that array X and a pointer pref_arr that points to X. I had no space in the scheme, but all the chars are qualified as const.

I then have the following code

function(const char*** pref_arr, int new_length) {
    const char** new_pref_arr = realloc(**pref_arr, sizeof(const char*) * new_length);
    // some other stuff to do...
}

where I am trying to reallocate the array X to a length new_length. The problem is, that my IDE warns me that passing const char* to a void* discards qualifiers.

Adam Bajger
  • 523
  • 7
  • 20
  • 2
    What is the declaration of `pref_arr`? – BearAqua May 28 '19 at 16:26
  • 2
    well... I just find out I am dereferencing too much... what a dumb mistake. Why I had to notice it only after spending 20 minutes on formatting of this question. – Adam Bajger May 28 '19 at 16:33
  • 2
    This is just a typo... it should be `realloc(*pref_arr, ...)` not `realloc(**pref_arr, ...)` – Dietrich Epp May 28 '19 at 16:34
  • 1
    @Adam Bajger You could still help others by editing more details into this question and answering it yourself. Also, I'd advise to edit out mentions of the "X" array, since it is nowhere present in your code. – BearAqua May 28 '19 at 16:35
  • 2
    I would advise to declare `struct`ures and toss out the stars. It's not good to be a [three star programmer](https://wiki.c2.com/?ThreeStarProgrammer) [archive link](https://web.archive.org/web/20190428023828/http://wiki.c2.com/?ThreeStarProgrammer). – KamilCuk May 28 '19 at 16:38
  • @KamilCuk the problem here is that I have to access it as an array of strings, but have to keep one pointer to the array in different places, so when I reallocate it somewhere, it will change also elsewhere. I can't see how a struct would make it easier. – Adam Bajger May 28 '19 at 16:50
  • 1
    For encapsulaion. For easier migration. For readability. For object-oriented-programming. `struct arrstr_s { char **strs; size_t cnt; }; int arrstr_resize(struct arrstr_s *t, size_t newlength) { void *pnt = realloc(t->strs, sizeof(*t->strs) * (t->cnt + 1)); t->strs = pnt; .... }` looks cleaner to me then `const char ***`. – KamilCuk May 28 '19 at 16:59
  • 1
    @Kamil Cuk but that just adds a lot of code and possibly marginal overheads. Isn't a better solution here to declare a macro? – BearAqua Jun 02 '19 at 20:11
  • I agree. A little typedef could also do sufficiently, I suppose. – Adam Bajger Jun 03 '19 at 07:39

1 Answers1

1

the problem here is, that you are dereferencing too much, one asterisk is precisely what you want, instead of two. See below:

function(const char*** pref_arr) {
    const char** new_pref_arr = realloc(*pref_arr, sizeof(const char*) * N);
    // some other stuff to do...
}

What were you doing in your code was that you were trying to reallocate the string A (because **pref_arr points precisely there - through double dereferencing), which is probably not what you wanted.

Adam Bajger
  • 523
  • 7
  • 20