1

I would like to hold a dynamic list of objects. I am not allowed to use VLAs, so I wrote the following function: (Originally this was a list of structs I defined, but I reproduced the same problem with strings.)

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

void appendSeq(char ** seq, char *** seqList, size_t curSeqListSize) {
    if (*seqList == NULL)
        *seqList = (char **) malloc(sizeof(char *));
    else
        *seqList = (char **) realloc(*seqList, sizeof(char *) * (curSeqListSize + 1));
    if (*seqList == NULL)
        exit(EXIT_FAILURE);
    *seqList[curSeqListSize] = *seq;
}

int main()
{
    char *curSeq = "";
    char ** seqList = NULL;

    for (int i = 0; i < 3; i++)
    {
        curSeq = "Sequence";
        char* curSeqCopy = strdup(curSeq);
        appendSeq(&curSeqCopy, &seqList, i);
    }
}

This fails with a segmentation error, and it seems that the realloc() function is not doing its job - Why?

WhozCraig
  • 65,258
  • 11
  • 75
  • 141
H.Rappeport
  • 517
  • 6
  • 17
  • where does it fail – pm100 Nov 13 '18 at 21:40
  • when you step through what value of i is the last value before it segfaults, what line does it segfault, what are the values of the params when it segfaults. – Bwebb Nov 13 '18 at 21:41
  • 4
    `*seqList[curSeqListSize]` ==> `(*seqList)[curSeqListSize]`. And fyi, you never adjust `curSeqListSize`, which ideally would be passed by pointer as well and updated accordingly for the caller. – WhozCraig Nov 13 '18 at 21:50
  • [don't cast malloc](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Barmar Nov 13 '18 at 21:54
  • @WhozCraig That solves it, thanks! If you'd like to post an answer I'd be happy to accept it. – H.Rappeport Nov 13 '18 at 21:55

1 Answers1

1

Your a victim of failing to understand operator precedence. In C, [] has higher precedence than *, so this:

*seqList[curSeqListSize] = ...

says "find the curSeqListSize slotted char** in the sequence of char** pointed to by seqList, then dereference that. That's wrong. You need to shove higher precedence in to your seqList expression, and () will do that:

(*seqList)[curSeqListSize] = ...

says "Get the char** pointed to by seqList, then get the curSeqListSize slotted char* from that.

I'd change a number of other things, but that's where your wheels fell off the wagon.

WhozCraig
  • 65,258
  • 11
  • 75
  • 141