Using Double Pointers after memory allocated within function

前端 未结 3 1859
自闭症患者
自闭症患者 2020-11-28 16:41

I was playing with double pointers in C and was wondering if I create a function that initializes the table, it crashes on going back to main when I try to make use of the m

相关标签:
3条回答
  • 2020-11-28 17:19

    The lines below InitStringTable() crash, because they are trying to perform operations on a memory address that is neither in the same scope as theirs nor have any reference to
    that memory address.

    The function InitStringTable() allocates memory to the table, but cannot be accessed by the
    calling function (here main), because the memory is local to the function in which it
    allocated.
    Therefore in order to use the same memory address for operations in the
    calling function you must pass a reference of that address to the calling function.

    In your program you can do it as under :
    Declare the function as :-

    char **InitStringTable(char **);
    
    
    int main()
    {
        char** strTable;
        strTable = InitStringTable(strTable);   
        strcpy(strTable[0], "abcdef");   
        strcpy(strTable[1], "xy");
    }   
    
    char **InitStringTable(char** table)
    {
       int i = 0;
    
       table = (char**)malloc(sizeof(char)*10);
    
       for(i = 0; i < 10; i++)
       {
          table[i] = (char*)malloc(sizeof(char)*50);
       }
    
       for(i = 0; i < 10; i++)
       {
          memset(table[i], 0, 50);
       }
    
       strcpy(table[0], "string1");
    
    
       /* after the function has finished its job, return the address of the table */    
       return table;
    }
    
    0 讨论(0)
  • 2020-11-28 17:21

    You have a pointer issue.

    It's like if you say:

    void inc(int a){
        a++;
    }
    
    int main(){
        int a = 0;
        inc(a);
        printf ("%d\n", a); // will display 0, not 1
    }
    

    does not work.

    You must pass &strTable instead of strTable as InitStringTable argument, and change other things in InitStringTable consequently ..
    Or just do strTable = InitStringTable(); , and return a char** from InitStringTable.

    0 讨论(0)
  • 2020-11-28 17:41

    C is pass by value.

    The value assigned to table is lost on returning from InitStringTable().


    Also when allocating pointers to char ask for room for pointers to char.

    So this:

    ... = (char**)malloc(sizeof(char)*10);
    

    shall at least be (assuming C):

    ... = malloc(sizeof(char*)*10);
    

    A possible approach to this would be:

    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    
    int InitStringTable(char *** ppptable, const size_t n, const size_t l)
    {
       int result = 0;
    
       if (NULL == ppptable)
       {
         result = -1;
         errno = EINVAL;
       }
       else
       {
         (*ppptable) = malloc(n * sizeof(**ppptable));
         if (NULL == (*ppptable))
         {
           result = -1;
         }
         else
         {
           size_t i = 0;
           for(; i < n; ++i)
           {
             (*ppptable)[i] = calloc(l, sizeof(*(*ppptable)[i]));
             if (NULL == (*ppptable)[i])
             {
               result = -1; 
    
               /* Failing in the middle requires clean-up. */
               for (; i > 0; --i)
               {
                 free((*ppptable)[i-1]);
               }
    
               free(*ppptable); 
               (*ppptable) = NULL;
    
               break;
             }
           }
         }
       }
    
       return result;
     }
    

    Call it like this:

    #include <stdlib.h>
    #include <stdio.h>
    
    int InitStringTable(char *** ppptable, const size_t n, const size_t l);
    
    int main(void)
    {
      int result = EXIT_SUCCESS;
      char ** strTable = NULL;
    
      if ( -1 == InitStringTable(&strTable, 10, 42)) //* Allocate array with 10 "strings" à 42 chars. */
      {
        perror("InitStringTable() failed");
        result = EXIT_FAILURE;
      }
      else
      {
        strcpy(strTable[0], "abcdef");
        strcpy(strTable[1], "xy");
      }
    
      return result;
    }
    

    And no, I won't get into this ridiculous "You don't wanna be a 3-star-programmer!" discussion.

    0 讨论(0)
提交回复
热议问题