2013-05-14 96 views
1

这与this question有关。我有一个函数void doConfig(mappings, int& numOfMappings),我不知道如何声明映射。它是一个二维数组,其元素是字符。第一个维度在运行时确定,并将在函数的主体中计算。第二个维度始终是2.这是什么代码?我想像它是char** mappings或类似的东西。另外在C++中,数组总是通过引用传递给对象?所以即使我打算在函数返回时使用该值,我也不需要使用&如何返回一个尺寸未知的二维数组?

编辑:基本上,我想回到这个char (*mapping)[2] = new char[numOfMappings][2];

按2to1mux的建议,我仍然无法得到它的工作。该数组似乎得到正确的值,但当doConfig()函数返回时出现错误。

int main() 
{ 
    int numOfMappings = 0; 
    char **mappings; 
    doConfig(mappings, numOfMappings); 
    cout << "This is mappings" << mappings << endl;//this address is different than the one given in doConfig(), is that wrong? 
    cout << "this is numOfMappings: " << numOfMappings << endl; 
    cout << mappings[0][0] << "->" << mappings[0][1] << endl;//program crashes here 
    //code removed 
    return EXIT_SUCCESS; 
} 

void doConfig(char **mappings, int& numOfMappings) 
{ 
    //code removed, numOfMappings calculated 
    for(int j = 0; j < numOfMappings; j++) 
    { 
     getline(settingsFile, setting); 
     mappings[j] = new char[2]; 
     mappings[j][0] = setting.at(0); 
     mappings[j][1] = setting.at(2); 
    } 
    for(int j = 0; j < numOfMappings; j++) 
     cout << mappings[j][0] << "->" << mappings[j][1] << endl;//everything is as expected so array created ok 
    cout << "This is mappings" << mappings << endl;//different address than the one give in main 
} 

好吧我现在正在工作,但主要来自周围。请人们解释一下如何知道何时使用*&

+0

我在看到您的编辑之前提供了一个答案。根据你的编辑,我现在感到困惑。你是说你在为函数内部的2d数组分配内存吗?然后你想返回一个指向你已经分配的内存的指针(然后你的担心是你不会知道函数外部的二维数组的大小,因为它是在函数中分配的)? – 2to1mux 2013-05-14 04:55:28

+0

@ 2to1mux是你刚刚说的是正确的 – Celeritas 2013-05-14 04:56:52

+0

我编辑了我的答案,以适应你的澄清。它有帮助吗? – 2to1mux 2013-05-14 06:35:46

回答

0

您可以返回一个指向2D数组的指针。

例如,

char **ptr; 


return ptr; 

虽然传递数组的地址,您就不必使用&运营商,如果你想通过二维数组的起始位置的地址,而不是地址的特定元素。

+0

但根据问题,我问我提供了一个链接,没有人说我可以声明它是char **,没有人解释,所以我不知道。 – Celeritas 2013-05-14 04:48:34

+0

从指针到1D数组的指针到二维数组的指针到底有什么区别? – 2013-05-16 18:03:00

1

我会回答你的问题,后进先出:

  1. 正确,你将不再需要在这里使用&

  2. 通过引用术语在技术上不适用于传递数组,但对于您的问题的简单答案是,您从未将数组的副本传递给函数。对array类型的参数所做的任何更改都将应用于原始数组,而不是副本。

  3. 我建议通过双指针:

    void doConfig(char **mappings, int& numOfMappings) 
    

    您将能够访问映射的成员完全按照自己的一个二维数组。例如:

    mappings[2][3] = 'b'; 
    

编辑:这是基于你的澄清

void doConfig(char** mappings, int& numOfMappings){ 

    /*Compute numOfMappings -- 
     this integer is passed by-reference, so it can be used outside function 
     to figure out the size allocated within the function*/ 

    mappings = new char*[numOfMappings]; 
    for(int i=0; i < numOfMappings; i++){ 
     mappings[i] = new char[2]; 
    } 
    /*Do whatever you need to do with mappings*/ 

    /*Return nothing because function is void -- since mappings is passed as 
     pointer, changes are maintained after function ends*/ 

} 
+0

我说得对吗? '字符**映射;'' doConfig(映射,numOfMappings);'' COUT <<映射[0] [0] << "->“<<映射[0] [1] << ENDL;' 崩溃 – Celeritas 2013-05-19 09:56:24

+0

是你给numOfMappings一个大于0的值吗?放入一些调试语句以确保你实际上正在分配一些非零的内存量。 – 2to1mux 2013-05-19 18:12:46

+0

我从来没有这样想过!哇2to1mux!通往GOO的途径 – 75inchpianist 2013-05-22 21:16:01

2

既然你标记你质疑C++,不C,我猜你可能要妥善解决新的建议。

template<typename T> 
using vectorOf2D = std::vector<std::array<T, 2>>; 

vectorOf2D<char> getMappings() { 
    return /* whatever you do to fill those */; 
    // (most probably) using NRVO to ellide the copy 
} 

如果你怕访问可能是复杂的:

auto mappings = getMappings(); 

functionTakingAMapping(mappings[i]); 
char element = mappings[0][1]; 
2

(对我的回答跟进到链接的问题。)

直接(还颇为曲折)语法此将是

char (*create_mappings(size_t n))[2] 
{ 
    // Allocate an char[n][2] array 
    char (*mappings)[2] = new char[n][2]; 

    // Initailize `mappings[i][j]` in any way you want... 

    return mappings; 
} 

但一个更好的主意是将其更容易通过typedef

typedef char Char2[2]; 

Char2 *create_mappings(size_t n) 
{ 
    // Allocate an char[n][2] array 
    Char2 *mappings = new Char2[n]; 

    // Initailize `mappings[i][j]` in any way you want... 

    return mappings; 
} 
+0

* Kill它杀死它!*不,真的,我的意思是说可以毫不费力地参与IOCCC,Typedef帮助很大。 – 2013-05-20 10:03:46