2014-09-10 52 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