How to allocate memory for pointers to pointers?











up vote
0
down vote

favorite












I am struggling with dynamic memory allocation. I can't see any mistakes but still get segmentation fault. Any comments on how i can improve my code are welcome.



 char* balanceStatements(char* lst) 
{
<some code>
char** bad = malloc(sizeof(char*)); // the list of the bad parts of char* lst
char* badOrder = &lst[0]; // the pointer to the first character of the part in lst
<some code>
bad = includeOrder(badOrder, bad);


includeOrder:



char** includeOrder(char* order, char** list)
{
static int i = 0;
list = realloc(list, sizeof(list) + sizeof(char*)); //allocation of memory for a new pointer in the list
list[i++] = order;
printf("vad %cn", list[0][0]);
return list;
}


the input that causes segfault is ""ZNGA 1300 2.66, CLH15.NYM 50 56.32 B, OWW 1000 11.623 B, OGG 20 580.1 B", the first part of it (ZNGA 1300 2.66) is bad, the parts are splitted with ','. This input "GOOG 300 542.0 B,AAPL 50 145.0 B,CSCO 250.0 29 B,GOOG 200 580.0 S", with the part "CSCO 250.0 29 B" being bad, does not cause the segfault. So is the cause of segfault in the improper memory allocation? If so how it should be done properly?



full code:



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

// result will be freed
char** includeOrder(char* order, char** list)
{
static int i = 0;
list = realloc(list, sizeof(list) + sizeof(char*)); //allocation of memory for a new pointer in the list
list[i++] = order;
printf("vad %cn", list[0][0]);
return list;
}



char* balanceStatements(char* lst) {
char type = 0;
double buy = 0;
double sell = 0;
int i = 0;
char tempQ[100] = {};
char tempP[100] = {};
char** bad = malloc(sizeof(char*)); // the list of the bad parts of char* lst
int nword = 0;
int k = 0;
int j = 0;
int isComma = 0;
char* badOrder = &lst[0]; // the pointer to the first character of the part in lst
printf("badOrder1 %c", badOrder[0]);
char* res = malloc(1000*sizeof(char));
res[0]="A";
while (lst[i]!='')
{
printf("char %cn", lst[i]);
if (lst[i] == ',')
{
printf("bbbb");
if (nword != 3)
{
printf("bad order 2 %cn", badOrder);
bad = includeOrder(badOrder, bad);
printf("asdan");
}
printf("aaaa");
if (isComma)
{
if (type == 'B') buy += atoi(tempQ) * atof(tempP);
else sell += atoi(tempQ) * atof(tempP);
}
printf("sssss");
nword = 0;
badOrder=&lst[++i];
isComma = 0;
k = 0;
j = 0;
}
if (lst[i] == ' ')
{
nword++;
i++;
}
if (nword == 0) i++;
if (nword == 1)
{
if (lst[i]>'9' || lst[i]<'0')
{
printf("bad ordern");
bad = includeOrder(badOrder, bad);
printf("svad %cn", bad[0][0]);
while(lst[++i]!=',');
}
else
{
tempQ[k++] = lst[i++];
}
}

if (nword == 2)
{
tempQ[k] = '';
printf("tempQ %sn", tempQ);
if(lst[i] == '.') isComma = 1;
printf("asdn");
if ( (lst[i] > '9' || lst[i] < '0') && lst[i] != '.')
{
includeOrder(badOrder, bad);
while(lst[++i]!=',');
}
else
{
tempP[j++] = lst[i++];
printf("lst %c tempP %cn", lst[i-1], tempP[j-1]);
}
}
if (nword == 3)
{
tempP[++j] = '';
printf("tempP %sn", tempP);
// sell
//fill in
if (lst[i] != 'B' && lst[i] !='S')
{
includeOrder(badOrder, bad);
while(lst[++i]!=',');
}
type = lst[i++];
}
/* if (nword == 4)
{
includeOrder(badOrder, bad);
while(lst[++i]!=',');
} */
}
if (type == 'S')
{
sell += atoi(tempQ) * atof(tempP);
}
else
{
buy += atoi(tempQ) * atof(tempP);
}
i=0;

// your code
printf("buy %fn", buy);
printf("sell %fn", sell);
printf("bad %cn", bad[0][0]);
int n = 0;
while (*(bad + n))
{
n++;
}
n--;
printf("size %in", n);
while (bad[0][i]!=',' && bad[0][i]!='')
{
printf("%c", bad[0][i++]);
}
sprintf(res, "Buy: %i Sell: %i", (int)buy, (int)sell);
if (bad)
{
res[strlen(res)]=';';
strcpy(&res[strlen(res)], " Badly formed ");
res[strlen(res)] = n+48;
res[strlen(res)] = ':';
res[strlen(res)] = ' ';
int i = 0;
while ( bad[0][i] != ',' )
{
res[strlen(res)] = bad[0][i++];
}
res[strlen(res)] = ' ';
res[strlen(res)] = ';';
}
return res;
}









share|improve this question


























    up vote
    0
    down vote

    favorite












    I am struggling with dynamic memory allocation. I can't see any mistakes but still get segmentation fault. Any comments on how i can improve my code are welcome.



     char* balanceStatements(char* lst) 
    {
    <some code>
    char** bad = malloc(sizeof(char*)); // the list of the bad parts of char* lst
    char* badOrder = &lst[0]; // the pointer to the first character of the part in lst
    <some code>
    bad = includeOrder(badOrder, bad);


    includeOrder:



    char** includeOrder(char* order, char** list)
    {
    static int i = 0;
    list = realloc(list, sizeof(list) + sizeof(char*)); //allocation of memory for a new pointer in the list
    list[i++] = order;
    printf("vad %cn", list[0][0]);
    return list;
    }


    the input that causes segfault is ""ZNGA 1300 2.66, CLH15.NYM 50 56.32 B, OWW 1000 11.623 B, OGG 20 580.1 B", the first part of it (ZNGA 1300 2.66) is bad, the parts are splitted with ','. This input "GOOG 300 542.0 B,AAPL 50 145.0 B,CSCO 250.0 29 B,GOOG 200 580.0 S", with the part "CSCO 250.0 29 B" being bad, does not cause the segfault. So is the cause of segfault in the improper memory allocation? If so how it should be done properly?



    full code:



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

    // result will be freed
    char** includeOrder(char* order, char** list)
    {
    static int i = 0;
    list = realloc(list, sizeof(list) + sizeof(char*)); //allocation of memory for a new pointer in the list
    list[i++] = order;
    printf("vad %cn", list[0][0]);
    return list;
    }



    char* balanceStatements(char* lst) {
    char type = 0;
    double buy = 0;
    double sell = 0;
    int i = 0;
    char tempQ[100] = {};
    char tempP[100] = {};
    char** bad = malloc(sizeof(char*)); // the list of the bad parts of char* lst
    int nword = 0;
    int k = 0;
    int j = 0;
    int isComma = 0;
    char* badOrder = &lst[0]; // the pointer to the first character of the part in lst
    printf("badOrder1 %c", badOrder[0]);
    char* res = malloc(1000*sizeof(char));
    res[0]="A";
    while (lst[i]!='')
    {
    printf("char %cn", lst[i]);
    if (lst[i] == ',')
    {
    printf("bbbb");
    if (nword != 3)
    {
    printf("bad order 2 %cn", badOrder);
    bad = includeOrder(badOrder, bad);
    printf("asdan");
    }
    printf("aaaa");
    if (isComma)
    {
    if (type == 'B') buy += atoi(tempQ) * atof(tempP);
    else sell += atoi(tempQ) * atof(tempP);
    }
    printf("sssss");
    nword = 0;
    badOrder=&lst[++i];
    isComma = 0;
    k = 0;
    j = 0;
    }
    if (lst[i] == ' ')
    {
    nword++;
    i++;
    }
    if (nword == 0) i++;
    if (nword == 1)
    {
    if (lst[i]>'9' || lst[i]<'0')
    {
    printf("bad ordern");
    bad = includeOrder(badOrder, bad);
    printf("svad %cn", bad[0][0]);
    while(lst[++i]!=',');
    }
    else
    {
    tempQ[k++] = lst[i++];
    }
    }

    if (nword == 2)
    {
    tempQ[k] = '';
    printf("tempQ %sn", tempQ);
    if(lst[i] == '.') isComma = 1;
    printf("asdn");
    if ( (lst[i] > '9' || lst[i] < '0') && lst[i] != '.')
    {
    includeOrder(badOrder, bad);
    while(lst[++i]!=',');
    }
    else
    {
    tempP[j++] = lst[i++];
    printf("lst %c tempP %cn", lst[i-1], tempP[j-1]);
    }
    }
    if (nword == 3)
    {
    tempP[++j] = '';
    printf("tempP %sn", tempP);
    // sell
    //fill in
    if (lst[i] != 'B' && lst[i] !='S')
    {
    includeOrder(badOrder, bad);
    while(lst[++i]!=',');
    }
    type = lst[i++];
    }
    /* if (nword == 4)
    {
    includeOrder(badOrder, bad);
    while(lst[++i]!=',');
    } */
    }
    if (type == 'S')
    {
    sell += atoi(tempQ) * atof(tempP);
    }
    else
    {
    buy += atoi(tempQ) * atof(tempP);
    }
    i=0;

    // your code
    printf("buy %fn", buy);
    printf("sell %fn", sell);
    printf("bad %cn", bad[0][0]);
    int n = 0;
    while (*(bad + n))
    {
    n++;
    }
    n--;
    printf("size %in", n);
    while (bad[0][i]!=',' && bad[0][i]!='')
    {
    printf("%c", bad[0][i++]);
    }
    sprintf(res, "Buy: %i Sell: %i", (int)buy, (int)sell);
    if (bad)
    {
    res[strlen(res)]=';';
    strcpy(&res[strlen(res)], " Badly formed ");
    res[strlen(res)] = n+48;
    res[strlen(res)] = ':';
    res[strlen(res)] = ' ';
    int i = 0;
    while ( bad[0][i] != ',' )
    {
    res[strlen(res)] = bad[0][i++];
    }
    res[strlen(res)] = ' ';
    res[strlen(res)] = ';';
    }
    return res;
    }









    share|improve this question
























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I am struggling with dynamic memory allocation. I can't see any mistakes but still get segmentation fault. Any comments on how i can improve my code are welcome.



       char* balanceStatements(char* lst) 
      {
      <some code>
      char** bad = malloc(sizeof(char*)); // the list of the bad parts of char* lst
      char* badOrder = &lst[0]; // the pointer to the first character of the part in lst
      <some code>
      bad = includeOrder(badOrder, bad);


      includeOrder:



      char** includeOrder(char* order, char** list)
      {
      static int i = 0;
      list = realloc(list, sizeof(list) + sizeof(char*)); //allocation of memory for a new pointer in the list
      list[i++] = order;
      printf("vad %cn", list[0][0]);
      return list;
      }


      the input that causes segfault is ""ZNGA 1300 2.66, CLH15.NYM 50 56.32 B, OWW 1000 11.623 B, OGG 20 580.1 B", the first part of it (ZNGA 1300 2.66) is bad, the parts are splitted with ','. This input "GOOG 300 542.0 B,AAPL 50 145.0 B,CSCO 250.0 29 B,GOOG 200 580.0 S", with the part "CSCO 250.0 29 B" being bad, does not cause the segfault. So is the cause of segfault in the improper memory allocation? If so how it should be done properly?



      full code:



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

      // result will be freed
      char** includeOrder(char* order, char** list)
      {
      static int i = 0;
      list = realloc(list, sizeof(list) + sizeof(char*)); //allocation of memory for a new pointer in the list
      list[i++] = order;
      printf("vad %cn", list[0][0]);
      return list;
      }



      char* balanceStatements(char* lst) {
      char type = 0;
      double buy = 0;
      double sell = 0;
      int i = 0;
      char tempQ[100] = {};
      char tempP[100] = {};
      char** bad = malloc(sizeof(char*)); // the list of the bad parts of char* lst
      int nword = 0;
      int k = 0;
      int j = 0;
      int isComma = 0;
      char* badOrder = &lst[0]; // the pointer to the first character of the part in lst
      printf("badOrder1 %c", badOrder[0]);
      char* res = malloc(1000*sizeof(char));
      res[0]="A";
      while (lst[i]!='')
      {
      printf("char %cn", lst[i]);
      if (lst[i] == ',')
      {
      printf("bbbb");
      if (nword != 3)
      {
      printf("bad order 2 %cn", badOrder);
      bad = includeOrder(badOrder, bad);
      printf("asdan");
      }
      printf("aaaa");
      if (isComma)
      {
      if (type == 'B') buy += atoi(tempQ) * atof(tempP);
      else sell += atoi(tempQ) * atof(tempP);
      }
      printf("sssss");
      nword = 0;
      badOrder=&lst[++i];
      isComma = 0;
      k = 0;
      j = 0;
      }
      if (lst[i] == ' ')
      {
      nword++;
      i++;
      }
      if (nword == 0) i++;
      if (nword == 1)
      {
      if (lst[i]>'9' || lst[i]<'0')
      {
      printf("bad ordern");
      bad = includeOrder(badOrder, bad);
      printf("svad %cn", bad[0][0]);
      while(lst[++i]!=',');
      }
      else
      {
      tempQ[k++] = lst[i++];
      }
      }

      if (nword == 2)
      {
      tempQ[k] = '';
      printf("tempQ %sn", tempQ);
      if(lst[i] == '.') isComma = 1;
      printf("asdn");
      if ( (lst[i] > '9' || lst[i] < '0') && lst[i] != '.')
      {
      includeOrder(badOrder, bad);
      while(lst[++i]!=',');
      }
      else
      {
      tempP[j++] = lst[i++];
      printf("lst %c tempP %cn", lst[i-1], tempP[j-1]);
      }
      }
      if (nword == 3)
      {
      tempP[++j] = '';
      printf("tempP %sn", tempP);
      // sell
      //fill in
      if (lst[i] != 'B' && lst[i] !='S')
      {
      includeOrder(badOrder, bad);
      while(lst[++i]!=',');
      }
      type = lst[i++];
      }
      /* if (nword == 4)
      {
      includeOrder(badOrder, bad);
      while(lst[++i]!=',');
      } */
      }
      if (type == 'S')
      {
      sell += atoi(tempQ) * atof(tempP);
      }
      else
      {
      buy += atoi(tempQ) * atof(tempP);
      }
      i=0;

      // your code
      printf("buy %fn", buy);
      printf("sell %fn", sell);
      printf("bad %cn", bad[0][0]);
      int n = 0;
      while (*(bad + n))
      {
      n++;
      }
      n--;
      printf("size %in", n);
      while (bad[0][i]!=',' && bad[0][i]!='')
      {
      printf("%c", bad[0][i++]);
      }
      sprintf(res, "Buy: %i Sell: %i", (int)buy, (int)sell);
      if (bad)
      {
      res[strlen(res)]=';';
      strcpy(&res[strlen(res)], " Badly formed ");
      res[strlen(res)] = n+48;
      res[strlen(res)] = ':';
      res[strlen(res)] = ' ';
      int i = 0;
      while ( bad[0][i] != ',' )
      {
      res[strlen(res)] = bad[0][i++];
      }
      res[strlen(res)] = ' ';
      res[strlen(res)] = ';';
      }
      return res;
      }









      share|improve this question













      I am struggling with dynamic memory allocation. I can't see any mistakes but still get segmentation fault. Any comments on how i can improve my code are welcome.



       char* balanceStatements(char* lst) 
      {
      <some code>
      char** bad = malloc(sizeof(char*)); // the list of the bad parts of char* lst
      char* badOrder = &lst[0]; // the pointer to the first character of the part in lst
      <some code>
      bad = includeOrder(badOrder, bad);


      includeOrder:



      char** includeOrder(char* order, char** list)
      {
      static int i = 0;
      list = realloc(list, sizeof(list) + sizeof(char*)); //allocation of memory for a new pointer in the list
      list[i++] = order;
      printf("vad %cn", list[0][0]);
      return list;
      }


      the input that causes segfault is ""ZNGA 1300 2.66, CLH15.NYM 50 56.32 B, OWW 1000 11.623 B, OGG 20 580.1 B", the first part of it (ZNGA 1300 2.66) is bad, the parts are splitted with ','. This input "GOOG 300 542.0 B,AAPL 50 145.0 B,CSCO 250.0 29 B,GOOG 200 580.0 S", with the part "CSCO 250.0 29 B" being bad, does not cause the segfault. So is the cause of segfault in the improper memory allocation? If so how it should be done properly?



      full code:



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

      // result will be freed
      char** includeOrder(char* order, char** list)
      {
      static int i = 0;
      list = realloc(list, sizeof(list) + sizeof(char*)); //allocation of memory for a new pointer in the list
      list[i++] = order;
      printf("vad %cn", list[0][0]);
      return list;
      }



      char* balanceStatements(char* lst) {
      char type = 0;
      double buy = 0;
      double sell = 0;
      int i = 0;
      char tempQ[100] = {};
      char tempP[100] = {};
      char** bad = malloc(sizeof(char*)); // the list of the bad parts of char* lst
      int nword = 0;
      int k = 0;
      int j = 0;
      int isComma = 0;
      char* badOrder = &lst[0]; // the pointer to the first character of the part in lst
      printf("badOrder1 %c", badOrder[0]);
      char* res = malloc(1000*sizeof(char));
      res[0]="A";
      while (lst[i]!='')
      {
      printf("char %cn", lst[i]);
      if (lst[i] == ',')
      {
      printf("bbbb");
      if (nword != 3)
      {
      printf("bad order 2 %cn", badOrder);
      bad = includeOrder(badOrder, bad);
      printf("asdan");
      }
      printf("aaaa");
      if (isComma)
      {
      if (type == 'B') buy += atoi(tempQ) * atof(tempP);
      else sell += atoi(tempQ) * atof(tempP);
      }
      printf("sssss");
      nword = 0;
      badOrder=&lst[++i];
      isComma = 0;
      k = 0;
      j = 0;
      }
      if (lst[i] == ' ')
      {
      nword++;
      i++;
      }
      if (nword == 0) i++;
      if (nword == 1)
      {
      if (lst[i]>'9' || lst[i]<'0')
      {
      printf("bad ordern");
      bad = includeOrder(badOrder, bad);
      printf("svad %cn", bad[0][0]);
      while(lst[++i]!=',');
      }
      else
      {
      tempQ[k++] = lst[i++];
      }
      }

      if (nword == 2)
      {
      tempQ[k] = '';
      printf("tempQ %sn", tempQ);
      if(lst[i] == '.') isComma = 1;
      printf("asdn");
      if ( (lst[i] > '9' || lst[i] < '0') && lst[i] != '.')
      {
      includeOrder(badOrder, bad);
      while(lst[++i]!=',');
      }
      else
      {
      tempP[j++] = lst[i++];
      printf("lst %c tempP %cn", lst[i-1], tempP[j-1]);
      }
      }
      if (nword == 3)
      {
      tempP[++j] = '';
      printf("tempP %sn", tempP);
      // sell
      //fill in
      if (lst[i] != 'B' && lst[i] !='S')
      {
      includeOrder(badOrder, bad);
      while(lst[++i]!=',');
      }
      type = lst[i++];
      }
      /* if (nword == 4)
      {
      includeOrder(badOrder, bad);
      while(lst[++i]!=',');
      } */
      }
      if (type == 'S')
      {
      sell += atoi(tempQ) * atof(tempP);
      }
      else
      {
      buy += atoi(tempQ) * atof(tempP);
      }
      i=0;

      // your code
      printf("buy %fn", buy);
      printf("sell %fn", sell);
      printf("bad %cn", bad[0][0]);
      int n = 0;
      while (*(bad + n))
      {
      n++;
      }
      n--;
      printf("size %in", n);
      while (bad[0][i]!=',' && bad[0][i]!='')
      {
      printf("%c", bad[0][i++]);
      }
      sprintf(res, "Buy: %i Sell: %i", (int)buy, (int)sell);
      if (bad)
      {
      res[strlen(res)]=';';
      strcpy(&res[strlen(res)], " Badly formed ");
      res[strlen(res)] = n+48;
      res[strlen(res)] = ':';
      res[strlen(res)] = ' ';
      int i = 0;
      while ( bad[0][i] != ',' )
      {
      res[strlen(res)] = bad[0][i++];
      }
      res[strlen(res)] = ' ';
      res[strlen(res)] = ';';
      }
      return res;
      }






      c memory-management






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 11 at 11:22









      norvd

      32




      32
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          0
          down vote



          accepted










          The most obvious error that will crash this program is in this line:



          list = realloc(list, sizeof(list) + sizeof(char*));


          sizeof() is a compile time operator (except for variable lenght arrays (VLA), but these are not here), that returns the size in bytes of the type of the argument. So sizeof(list) return the size of a char**, not the allocated size of the object. There is not a function that returns the allocated size of a dynamic memory block in C, you have to keep track of that yourself, in an additional variable.



          char** includeOrder(char* order, char** list, size_t *list_len)
          {
          list = realloc(list, *list_len + sizeof(char*));
          ...
          return list;
          }


          And then in the main function:



          size_t list_len = sizeof(char*); //0 is also valid
          char** bad = malloc(list_len);
          ...
          bad = includeOrder(badOrder, bad, &list_len);


          Now that you are into pass-by-pointer functions you could do the same for the list variable:



          void includeOrder(char* order, char*** list, size_t *list_len)
          {
          *list = realloc(*list, *list_len + sizeof(char*));
          ...
          }





          share|improve this answer























          • ok, got it, the static int i looks like a good option for it, what if i use it like list = realloc(list, (i + 1) * sizeof(char*));?
            – norvd
            Nov 11 at 11:35










          • @norvd: Usually the size of the list should be in the same place as the list itself. If bad is a local variable, then bad_len should be a local variable, too. Also think if you want it as number of bytes or number of elements. My code assumed number of bytes but your comment is number of elements; either one is good.
            – rodrigo
            Nov 11 at 11:38










          • @norvd: A sensible approach would be to create a type struct string_list { char **ptr; size_t len; } and a function string_list_add() that does the hard work.
            – rodrigo
            Nov 11 at 11:39


















          up vote
          0
          down vote













          Your problem is a misunderstanding of sizeof(list). sizeof returns the memory size of list, i.e. the size of a char**. It doesn't take into consideration the number of elements in your list.



          Keep in mind that sizeof isn't a function that is executed during runtime. It is a compile time unary operator.






          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53248212%2fhow-to-allocate-memory-for-pointers-to-pointers%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            2 Answers
            2






            active

            oldest

            votes








            2 Answers
            2






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            0
            down vote



            accepted










            The most obvious error that will crash this program is in this line:



            list = realloc(list, sizeof(list) + sizeof(char*));


            sizeof() is a compile time operator (except for variable lenght arrays (VLA), but these are not here), that returns the size in bytes of the type of the argument. So sizeof(list) return the size of a char**, not the allocated size of the object. There is not a function that returns the allocated size of a dynamic memory block in C, you have to keep track of that yourself, in an additional variable.



            char** includeOrder(char* order, char** list, size_t *list_len)
            {
            list = realloc(list, *list_len + sizeof(char*));
            ...
            return list;
            }


            And then in the main function:



            size_t list_len = sizeof(char*); //0 is also valid
            char** bad = malloc(list_len);
            ...
            bad = includeOrder(badOrder, bad, &list_len);


            Now that you are into pass-by-pointer functions you could do the same for the list variable:



            void includeOrder(char* order, char*** list, size_t *list_len)
            {
            *list = realloc(*list, *list_len + sizeof(char*));
            ...
            }





            share|improve this answer























            • ok, got it, the static int i looks like a good option for it, what if i use it like list = realloc(list, (i + 1) * sizeof(char*));?
              – norvd
              Nov 11 at 11:35










            • @norvd: Usually the size of the list should be in the same place as the list itself. If bad is a local variable, then bad_len should be a local variable, too. Also think if you want it as number of bytes or number of elements. My code assumed number of bytes but your comment is number of elements; either one is good.
              – rodrigo
              Nov 11 at 11:38










            • @norvd: A sensible approach would be to create a type struct string_list { char **ptr; size_t len; } and a function string_list_add() that does the hard work.
              – rodrigo
              Nov 11 at 11:39















            up vote
            0
            down vote



            accepted










            The most obvious error that will crash this program is in this line:



            list = realloc(list, sizeof(list) + sizeof(char*));


            sizeof() is a compile time operator (except for variable lenght arrays (VLA), but these are not here), that returns the size in bytes of the type of the argument. So sizeof(list) return the size of a char**, not the allocated size of the object. There is not a function that returns the allocated size of a dynamic memory block in C, you have to keep track of that yourself, in an additional variable.



            char** includeOrder(char* order, char** list, size_t *list_len)
            {
            list = realloc(list, *list_len + sizeof(char*));
            ...
            return list;
            }


            And then in the main function:



            size_t list_len = sizeof(char*); //0 is also valid
            char** bad = malloc(list_len);
            ...
            bad = includeOrder(badOrder, bad, &list_len);


            Now that you are into pass-by-pointer functions you could do the same for the list variable:



            void includeOrder(char* order, char*** list, size_t *list_len)
            {
            *list = realloc(*list, *list_len + sizeof(char*));
            ...
            }





            share|improve this answer























            • ok, got it, the static int i looks like a good option for it, what if i use it like list = realloc(list, (i + 1) * sizeof(char*));?
              – norvd
              Nov 11 at 11:35










            • @norvd: Usually the size of the list should be in the same place as the list itself. If bad is a local variable, then bad_len should be a local variable, too. Also think if you want it as number of bytes or number of elements. My code assumed number of bytes but your comment is number of elements; either one is good.
              – rodrigo
              Nov 11 at 11:38










            • @norvd: A sensible approach would be to create a type struct string_list { char **ptr; size_t len; } and a function string_list_add() that does the hard work.
              – rodrigo
              Nov 11 at 11:39













            up vote
            0
            down vote



            accepted







            up vote
            0
            down vote



            accepted






            The most obvious error that will crash this program is in this line:



            list = realloc(list, sizeof(list) + sizeof(char*));


            sizeof() is a compile time operator (except for variable lenght arrays (VLA), but these are not here), that returns the size in bytes of the type of the argument. So sizeof(list) return the size of a char**, not the allocated size of the object. There is not a function that returns the allocated size of a dynamic memory block in C, you have to keep track of that yourself, in an additional variable.



            char** includeOrder(char* order, char** list, size_t *list_len)
            {
            list = realloc(list, *list_len + sizeof(char*));
            ...
            return list;
            }


            And then in the main function:



            size_t list_len = sizeof(char*); //0 is also valid
            char** bad = malloc(list_len);
            ...
            bad = includeOrder(badOrder, bad, &list_len);


            Now that you are into pass-by-pointer functions you could do the same for the list variable:



            void includeOrder(char* order, char*** list, size_t *list_len)
            {
            *list = realloc(*list, *list_len + sizeof(char*));
            ...
            }





            share|improve this answer














            The most obvious error that will crash this program is in this line:



            list = realloc(list, sizeof(list) + sizeof(char*));


            sizeof() is a compile time operator (except for variable lenght arrays (VLA), but these are not here), that returns the size in bytes of the type of the argument. So sizeof(list) return the size of a char**, not the allocated size of the object. There is not a function that returns the allocated size of a dynamic memory block in C, you have to keep track of that yourself, in an additional variable.



            char** includeOrder(char* order, char** list, size_t *list_len)
            {
            list = realloc(list, *list_len + sizeof(char*));
            ...
            return list;
            }


            And then in the main function:



            size_t list_len = sizeof(char*); //0 is also valid
            char** bad = malloc(list_len);
            ...
            bad = includeOrder(badOrder, bad, &list_len);


            Now that you are into pass-by-pointer functions you could do the same for the list variable:



            void includeOrder(char* order, char*** list, size_t *list_len)
            {
            *list = realloc(*list, *list_len + sizeof(char*));
            ...
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 11 at 11:36

























            answered Nov 11 at 11:32









            rodrigo

            62.4k490127




            62.4k490127












            • ok, got it, the static int i looks like a good option for it, what if i use it like list = realloc(list, (i + 1) * sizeof(char*));?
              – norvd
              Nov 11 at 11:35










            • @norvd: Usually the size of the list should be in the same place as the list itself. If bad is a local variable, then bad_len should be a local variable, too. Also think if you want it as number of bytes or number of elements. My code assumed number of bytes but your comment is number of elements; either one is good.
              – rodrigo
              Nov 11 at 11:38










            • @norvd: A sensible approach would be to create a type struct string_list { char **ptr; size_t len; } and a function string_list_add() that does the hard work.
              – rodrigo
              Nov 11 at 11:39


















            • ok, got it, the static int i looks like a good option for it, what if i use it like list = realloc(list, (i + 1) * sizeof(char*));?
              – norvd
              Nov 11 at 11:35










            • @norvd: Usually the size of the list should be in the same place as the list itself. If bad is a local variable, then bad_len should be a local variable, too. Also think if you want it as number of bytes or number of elements. My code assumed number of bytes but your comment is number of elements; either one is good.
              – rodrigo
              Nov 11 at 11:38










            • @norvd: A sensible approach would be to create a type struct string_list { char **ptr; size_t len; } and a function string_list_add() that does the hard work.
              – rodrigo
              Nov 11 at 11:39
















            ok, got it, the static int i looks like a good option for it, what if i use it like list = realloc(list, (i + 1) * sizeof(char*));?
            – norvd
            Nov 11 at 11:35




            ok, got it, the static int i looks like a good option for it, what if i use it like list = realloc(list, (i + 1) * sizeof(char*));?
            – norvd
            Nov 11 at 11:35












            @norvd: Usually the size of the list should be in the same place as the list itself. If bad is a local variable, then bad_len should be a local variable, too. Also think if you want it as number of bytes or number of elements. My code assumed number of bytes but your comment is number of elements; either one is good.
            – rodrigo
            Nov 11 at 11:38




            @norvd: Usually the size of the list should be in the same place as the list itself. If bad is a local variable, then bad_len should be a local variable, too. Also think if you want it as number of bytes or number of elements. My code assumed number of bytes but your comment is number of elements; either one is good.
            – rodrigo
            Nov 11 at 11:38












            @norvd: A sensible approach would be to create a type struct string_list { char **ptr; size_t len; } and a function string_list_add() that does the hard work.
            – rodrigo
            Nov 11 at 11:39




            @norvd: A sensible approach would be to create a type struct string_list { char **ptr; size_t len; } and a function string_list_add() that does the hard work.
            – rodrigo
            Nov 11 at 11:39












            up vote
            0
            down vote













            Your problem is a misunderstanding of sizeof(list). sizeof returns the memory size of list, i.e. the size of a char**. It doesn't take into consideration the number of elements in your list.



            Keep in mind that sizeof isn't a function that is executed during runtime. It is a compile time unary operator.






            share|improve this answer

























              up vote
              0
              down vote













              Your problem is a misunderstanding of sizeof(list). sizeof returns the memory size of list, i.e. the size of a char**. It doesn't take into consideration the number of elements in your list.



              Keep in mind that sizeof isn't a function that is executed during runtime. It is a compile time unary operator.






              share|improve this answer























                up vote
                0
                down vote










                up vote
                0
                down vote









                Your problem is a misunderstanding of sizeof(list). sizeof returns the memory size of list, i.e. the size of a char**. It doesn't take into consideration the number of elements in your list.



                Keep in mind that sizeof isn't a function that is executed during runtime. It is a compile time unary operator.






                share|improve this answer












                Your problem is a misunderstanding of sizeof(list). sizeof returns the memory size of list, i.e. the size of a char**. It doesn't take into consideration the number of elements in your list.



                Keep in mind that sizeof isn't a function that is executed during runtime. It is a compile time unary operator.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 11 at 11:28









                Maxime Chéramy

                9,39443160




                9,39443160






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53248212%2fhow-to-allocate-memory-for-pointers-to-pointers%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    Xamarin.iOS Cant Deploy on Iphone

                    Glorious Revolution

                    Dulmage-Mendelsohn matrix decomposition in Python