2014-09-10 53 views
1

我在C中使用双指针,并想知道如果我创建了一个初始化表的函数,当我尝试使用分配给内存的内存时,它在返回主时崩溃InitStringTable。我相信一个简单的解决方法是使strTable成为全局的,然后我相信它是可以的,但是我不想这样做,因为这对我来说更像是一个学习练习,用于修改表格,即我应该能够从InitStringTable之后的主要或另一个函数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"); 
} 
+2

除了你投'malloc'(你不应该用C做)的事实,这是怎么与C++相关,你应该使用'std :: string','std :: vector',而不是使用原始指针? – crashmstr 2014-09-10 15:33:28

+0

看起来你需要改变'table =(char **)malloc(sizeof(char)* 10);'to'table =(char **)malloc(sizeof(char *)* 10);'因为'table'是一个'char *'的数组。 – abiessu 2014-09-10 15:33:58

+1

为什么你的函数无效?为什么不把返回值用于有用的东西? – wildplasser 2014-09-10 15:47:33

回答

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

不,我不会陷入这种荒谬的“你不想成为一个三星程序员!”讨论。

+0

感谢您的解决方案。是的,我在代码中分配一个char数组的地方犯了一个错误,它应该是char *数组。您的解决方案非常优雅,因为我忘记了在调用malloc之后添加NULL检查。 char ***可能看起来很有趣,但我认为它有助于强调C按默认值进行调用,这是我在编写该案例时忘记的。谢谢! – ashton71 2014-09-10 23:42:16

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(); ,并从InitStringTable返回char**

+0

呃......为什么没有缩进? – GingerPlusPlus 2014-09-10 15:44:27

+0

现在缩进.. – Vincent 2014-09-10 15:47:30

+0

感谢您的解释。 – ashton71 2014-09-10 23:52:20

0

下面InitStringTable的线()碰撞,因为它们试图执行上既不是在相同的范围,因为他们也不必须
该存储器地址的任何参考的存储器地址的操作 。

功能InitStringTable()分配内存表,但不能由
调用函数(这里主要)进行访问,因为内存是本地其中
分配的功能。
因此,为了在调用函数中使用相同的内存地址进行操作,您必须将该地址的引用传递给调用函数。

在你的程序,你可以做到这一点为下:
声明功能: -

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

感谢您的解决方案。我看到返回字符**的优点,但是我从字符串论证中看到了进一步的理解。 – ashton71 2014-09-10 23:50:21