title: C - Why is the dynamic array not initializing properly?
body: <p>I have made this sample program that represents exactly my problem.
  I am trying to make a list of string, since the total amount of strings that will be stored in the list is unknown at compile time I'm using calloc/realloc
  to allocate size on the heap at runtime.
  The reason why I am using functions to initialize, modify, and free the list
  is because in my original program there are 3 dynamic lists to be created, all 3 are arrays of strings.
  init_pathlist(), add_to_pathlist() and clear_pathlist() are only wrappers for the code I found in stack overflow on a similar question. </p>
  
  <p>When it reaches the memcmp(element, array[i], MAXSTRLEN) I get a SIGSEGV error, valgrind tells me that array[i] is unmapped. Why is the dynamic array string_element not initializing properly?
  Note: I tried replacing "*string_element" by "**string_element" and changing all calls to functions from "&amp;string_element" to "string_element" and had the same results.</p>
  
  <p>I am fairly new to memory management and would really apreciate your help.
  Here's the code in question:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;errno.h&gt;
  #include &lt;stdlib.h&gt;
  size_t ARRSIZE = 1024;
  size_t MAXSTRLEN = 1024;
  
  void clear_list(char** array)
  {
    int i;
    for(i = 0; i &lt; ARRSIZE; i++)
      free(array[i]);
    free(array);
  }
  
  void init_list(char** marray)
  {
    int i;
    char** array;
    array = calloc(ARRSIZE , sizeof(char*));
  
    for(i = 0; i &lt; ARRSIZE; i++) {
      array[i] = calloc(MAXSTRLEN +1, sizeof (char));
      if (array[i] == NULL){
        perror("calloc");
        exit(1);
      }
    }
    marray = array;
  }
  
  void add_to_list(char* element, char** array, int pos)
  {
    int i;
    int NEWSIZE;
  
    if(pos == ARRSIZE) {
      NEWSIZE = (ARRSIZE + 2) * 2;
  
      char **newptr = realloc(array, NEWSIZE * sizeof(*array));
      if (newptr == NULL){
        clear_list(array); 
        perror("realloc");
        exit(1);
      }
      ARRSIZE = NEWSIZE;
      array = newptr;
      for (i = pos; i &lt; ARRSIZE; i++) {
        array[i] = calloc((MAXSTRLEN + 1) , sizeof (char));
        if (array[i] == NULL){
          perror("calloc");  
          exit(1);
        }
      }
    }
    strncpy(array[pos], element, MAXSTRLEN);
  }
  
  
  int testloop( char *element, char** array, int pos)
  {
    int i;
    printf("Element to add: %s\n", element);
    for(i = 0; i &lt; (pos -1); i++){
      if (memcmp(element, array[i], MAXSTRLEN) == 0)
        return 1;
  
    }
    add_to_list(element, array, pos);
    return 0;
  }
  
  int main(void)
  {
    int loop_ret, position = 0;
    char element[100];
    char *string_element;
  
    init_list(&amp;string_element);
  
    printf("Enter an element: \n");
    while(scanf("%s", element) != EOF) {
      loop_ret = testloop(element, &amp;string_element, position);
      ++position;
      if (loop_ret == 0)
        continue;
      else if (loop_ret == 1) {
        printf("%s match one of string_element entries\n", element);
        exit(0);
      }
    }
  
    clear_list(&amp;string_element);
    return 0;
  }
  </code></pre>
  
  <p>And Here is a sample run:</p>
  
  <pre><code>$ ./2d_char_array_funcparam 
  Enter an element: 
  bob
  Element to add: bob
  flo
  Element to add: flo
  Segmentation fault (core dumped)
  </code></pre>
  
  <p>Here's what valgrind tells me:</p>
  
  <pre><code>$ valgrind --track-origins=yes ./2d_char_array_funcparam
  ==8944== Memcheck, a memory error detector
  ==8944== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
  ==8944== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
  ==8944== Command: ./2d_char_array_funcparam
  ==8944== 
  Enter an element: 
  bob
  Element to add: bob
  ==8944== Use of uninitialised value of size 8
  ==8944==    at 0x4C2E7BC: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==8944==    by 0x400A97: add_to_list (2d_char_array_funcparam.c:58)
  ==8944==    by 0x400B2D: testloop (2d_char_array_funcparam.c:72)
  ==8944==    by 0x400B90: main (2d_char_array_funcparam.c:86)
  ==8944==  Uninitialised value was created by a stack allocation
  ==8944==    at 0x400B39: main (2d_char_array_funcparam.c:77)
  ==8944== 
  ==8944== Conditional jump or move depends on uninitialised value(s)
  ==8944==    at 0x4C2E7DC: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==8944==    by 0x400A97: add_to_list (2d_char_array_funcparam.c:58)
  ==8944==    by 0x400B2D: testloop (2d_char_array_funcparam.c:72)
  ==8944==    by 0x400B90: main (2d_char_array_funcparam.c:86)
  ==8944==  Uninitialised value was created by a stack allocation
  ==8944==    at 0x400B39: main (2d_char_array_funcparam.c:77)
  ==8944== 
  ==8944== Conditional jump or move depends on uninitialised value(s)
  ==8944==    at 0x4C2E7F1: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==8944==    by 0x400A97: add_to_list (2d_char_array_funcparam.c:58)
  ==8944==    by 0x400B2D: testloop (2d_char_array_funcparam.c:72)
  ==8944==    by 0x400B90: main (2d_char_array_funcparam.c:86)
  ==8944==  Uninitialised value was created by a stack allocation
  ==8944==    at 0x400B39: main (2d_char_array_funcparam.c:77)
  ==8944== 
  ==8944== Use of uninitialised value of size 8
  ==8944==    at 0x4C2E84C: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==8944==    by 0x400A97: add_to_list (2d_char_array_funcparam.c:58)
  ==8944==    by 0x400B2D: testloop (2d_char_array_funcparam.c:72)
  ==8944==    by 0x400B90: main (2d_char_array_funcparam.c:86)
  ==8944==  Uninitialised value was created by a stack allocation
  ==8944==    at 0x400B39: main (2d_char_array_funcparam.c:77)
  ==8944== 
  ==8944== Conditional jump or move depends on uninitialised value(s)
  ==8944==    at 0x4C2E85B: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==8944==    by 0x400A97: add_to_list (2d_char_array_funcparam.c:58)
  ==8944==    by 0x400B2D: testloop (2d_char_array_funcparam.c:72)
  ==8944==    by 0x400B90: main (2d_char_array_funcparam.c:86)
  ==8944==  Uninitialised value was created by a stack allocation
  ==8944==    at 0x400B39: main (2d_char_array_funcparam.c:77)
  ==8944== 
  robert
  Element to add: robert
  ==8944== Invalid write of size 1
  ==8944==    at 0x4C2E7BC: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==8944==    by 0x400A97: add_to_list (2d_char_array_funcparam.c:58)
  ==8944==    by 0x400B2D: testloop (2d_char_array_funcparam.c:72)
  ==8944==    by 0x400B90: main (2d_char_array_funcparam.c:86)
  ==8944==  Address 0x747265626f72 is not stack'd, malloc'd or (recently) free'd
  ==8944== 
  ==8944== 
  ==8944== Process terminating with default action of signal 11 (SIGSEGV)
  ==8944==  Access not within mapped region at address 0x747265626F72
  ==8944==    at 0x4C2E7BC: __strncpy_sse2_unaligned (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==8944==    by 0x400A97: add_to_list (2d_char_array_funcparam.c:58)
  ==8944==    by 0x400B2D: testloop (2d_char_array_funcparam.c:72)
  ==8944==    by 0x400B90: main (2d_char_array_funcparam.c:86)
  ==8944==  If you believe this happened as a result of a stack
  ==8944==  overflow in your program's main thread (unlikely but
  ==8944==  possible), you can try to increase the size of the
  ==8944==  main thread stack using the --main-stacksize= flag.
  ==8944==  The main thread stack size used in this run was 8388608.
  ==8944== 
  ==8944== HEAP SUMMARY:
  ==8944==     in use at exit: 1,057,792 bytes in 1,025 blocks
  ==8944==   total heap usage: 1,025 allocs, 0 frees, 1,057,792 bytes allocated
  ==8944== 
  ==8944== LEAK SUMMARY:
  ==8944==    definitely lost: 8,192 bytes in 1 blocks
  ==8944==    indirectly lost: 1,049,600 bytes in 1,024 blocks
  ==8944==      possibly lost: 0 bytes in 0 blocks
  ==8944==    still reachable: 0 bytes in 0 blocks
  ==8944==         suppressed: 0 bytes in 0 blocks
  ==8944== Rerun with --leak-check=full to see details of leaked memory
  ==8944== 
  ==8944== For counts of detected and suppressed errors, rerun with: -v
  ==8944== ERROR SUMMARY: 2049 errors from 6 contexts (suppressed: 0 from 0)
  Segmentation fault (core dumped)
  </code></pre>
  
  <p>Thanks for your time!</p>