在函数内分配内存后使用双指针

时间:2014-09-10 15:31:32

标签: c pointers

我正在玩C中的双指针,并且想知道我是否创建了一个初始化表的函数,当我尝试使用InitStringTable分配的内存时,它会在返回main时崩溃。我相信一个简单的解决方法是使strTable全局化,然后我相信它没问题,但我不想这样做,因为这对我来说是一个学习练习,可以通过表格进行修改,即我应该能够修改strTable来自在InitStringTable之后的main或另一个函数modifyTable。  感谢您提供任何帮助。

int main()
{
    char** strTable;

    // Allocates memory for string table.
    InitStringTable(strTable);
    // Below lines should be able to copy strings into newly allocated table.
    // Below lines cause crash however.
    strcpy(strTable[0], "abcdef");

    strcpy(strTable[1], "xy");
}

// Allocates memory for the string table. This function should create a table
// of size 10 strings with each string 50 chars long. The code compiles fine.
void 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");
}

3 个答案:

答案 0 :(得分:5)

C是按值传递的。

table返回时,分配给InitStringTable()的值会丢失。


同样,在分配指向char的指针时,请求指向char的指针。

所以这个:

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

至少应为(假设C):

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

可能的方法是:

#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;
 }

这样称呼:

#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;
}

不,我不会陷入这种荒谬的过程中#34;你不想成为一名三星级程序员!&#34;讨论

答案 1 :(得分:0)

你有指针问题。

如果你说:

void inc(int a){
    a++;
}

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

不起作用。

您必须将&strTable代替strTable作为InitStringTable参数,然后更改InitStringTable中的其他内容。
或者只做strTable = InitStringTable(); ,并从char**返回InitStringTable

答案 2 :(得分:0)

InitStringTable()下面的行崩溃,因为他们正在尝试执行操作 在一个与他们的范围不同的内存地址上,也没有任何引用 记忆地址。

函数InitStringTable()为表分配内存,但无法访问 调用函数(这里是main),因为内存是函数所在的本地 分配。
因此,为了使用相同的内存地址进行操作 调用函数必须将该地址的引用传递给调用函数。

在你的程序中,你可以这样做:
将函数声明为: -

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;
}