2012-10-25 28 views
0

我是VC++的新手,我需要在函数之间传递4个数组,所以我使用另一个数组来存储它们的指针。我做对了吗?VC++:在函数之间传递多个数组

unsigned int* step1(...) { 

    ... 

    // save data arrays 
    unsigned int* savedData = new unsigned int[4]; 
    savedData[0] = *data0; 
    savedData[1] = *data1; 
    savedData[2] = *data2; 
    savedData[3] = *data3; 
    return savedData; 
} 

unsigned char* step2(unsigned int* savedData, ...) { 

    // read data arrays 
    unsigned int* data0 = &savedData[0]; 
    unsigned int* data1 = &savedData[1]; 
    unsigned int* data2 = &savedData[2]; 
    unsigned int* data3 = &savedData[3]; 

    ... 

} 
+0

'4个函数之间的数组'你没有4个数组。你有1个包含4个元素的数组。 –

+0

不,data0-4是在函数中动态分配的实际数组。 –

+0

我推荐阅读一些[C++书籍](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list)。 –

回答

1

使用std :: vector。

std::vector<int> data; 
data.push_back(data0); 
data.push_back(data1); 
data.push_back(data2); 
data.push_back(data3); 

而且

int data0 = data[0]; 
int data1 = data[1]; 
int data2 = data[2]; 
int data3 = data[3]; 

,并添加一些代码,这些函数将被使用。

+0

是'std :: vector's与GCC兼容吗? –

+0

是的,STL是C++ standart的一部分。 – kuperspb

+0

但是当我这样做时,函数退出时,数据向量是否会被系统取消分配? –

1

您将需要一个指针数组,例如:

//The function that takes the array 
void foo(char ** data) 
{ 
    std::cout << data[0]; 
    std::cout << data[1]; 
    std::cout << data[2]; 
} 

main() 
{ 
    char * str = "aaa"; 
    char * str1 = "sss"; 
    char * str2 = "ddd"; 
    char ** res = new char *[3];//here's your array that has 3 elements each of which is a pointer. 
    res[0]=str; 
    res[1]=str1; 
    res[2]=str2; 
    foo(res); 
    return 0; 
} 

输出将是

aaasssddd 

一个稍微好一点的方法:

这将是更好地使用stl容器,而不是原始指针,因为它们更简单,更安全。在指针上,将工作方式相同:

void foo(std::vector< char * >vec) 
{ 
    std::cout << vec[0]; 
    std::cout << vec[1]; 
    std::cout << vec[2]; 
} 

main() 
{ 
    char * str = "aaa"; 
    char * str1 = "sss"; 
    char * str2 = "ddd"; 
    std::vector< char * >vec; 
    vec.push_back(str); 
    vec.push_back(str1); 
    vec.push_back(str2); 

    foo(vec); 
return 0; 
} 

进一步改进的方式:

最后,最好的办法就是使用字符串:

void foo(std::vector<std::string>vec) 
{ 
    std::cout << vec[0]; 
    std::cout << vec[1]; 
    std::cout << vec[2]; 
} 

main() 
{ 
    std::string str = "aaa"; 
    std::string str1 = "sss"; 
    std::string str2 = "ddd"; 
    std::vector<std::string>vec; 
    vec.push_back(str); 
    vec.push_back(str1); 
    vec.push_back(str2); 

    foo(vec); 
return 0; 
} 
+1

您需要通过const引用传递向量以避免过度复制。 – kuperspb

1

假设你真的想你写的问题(4个阵列分组成一个),首先你需要4个阵列,例如int

int data1[] = {1,2,3,4}; 
int data2[] = {5,6,7,8,9,10}; 
int *data3; // Let's say those two were allocated by malloc/new 
int *data4; 

// Now array that will contain those values 
int **data = new (int*)[4]; // int * = your datatype (array of ints) 
          // (int*)[] = array of arrays of ints 
data[0] = data1; 
data[1] = data2; 
data[2] = data3; 
data[3] = data4; 


// And reverse function 
data1 = data[0]; 
data2 = data[1]; 
data3 = data[2]; 
data4 = data[3]; 

几点注意事项:

    ,如果你想拥有这些“阵列”调整大小使用(或时间后,使用超过4项)使用 std::vector
  • 另一STL Container
  • 如果这些数据区块有任何特殊这意味着(如data1 =用户ID,data2 =访客IDS,...)建类或结构,将其命名为:

    // In C: 
    struct user_data{ 
        int *user_ids; 
        int *visitor_ids; 
        char **unregistered_user_names; // Feel free to use another types 
    } 
    
    // In C++ 
    class UserData { 
        std::vector<int> userIds; 
        std::vector<int> visitorIds; 
        std::vector<std::string> unregisteredUserNames; 
    } 
    
  • 一旦人与new unsigned int [4]位于数据不要忘记释放内存与delete [] array

+0

你的第一个例子不能在VS2010中编译。是说“C2440:'=':无法从'int *'转换为'int'” –

+0

而且我需要动态分配数据数组,以便在函数退出后不会GC'd。 –

+0

你的例子仍然不能在VS2010中编译,它说“错误:类型名称现在被允许”。错误在'new(* int)' –

3

为了完成前一个有效的答案,我会尽力扩大了答案:

Have I done it correctly?

好了,为了传递数据函数之间:是的,用指针来做是一个选项。但社区普遍不鼓励它,因为这会让内存管理变得麻烦。

当您使用指向动态内存的指针时,必须清楚地知道WHERE内存被创建以及内存将被删除的位置,换句话说:内存的生命周期必须清晰直接,出于这个原因,通常不鼓励在函数之间传递指针。

例如,在你的案例:unsigned int* step1(...)函数返回一个指针,但看着它,一个新的程序员或者有人说,你的工作就不会告诉我们,如果返回的指针是动态内存,如果调用第一步必须deletedelete []通话后的记忆,unsigned char* step2(unsigned int* savedData, ...)也一样,会更混乱和麻烦,因为有人会问:step2会改变savedData通过?

为了解决step2问题,您可以将功能更改为:

unsigned char* step2(const unsigned int* const savedData, ...) 

通过添加const你告诉:“嘿step2是不会改变的savedData的内容,也不!改变它指向的地址“。

但以前的所有文本都没用,因为没有解决最重要的问题:内存何时被释放?

step1中,您正在动态创建内存,在step2这个内存得到了补充,但是... delete隐藏在您不粘贴的代码中的某个地方?或者有一个step3等待照顾内存?

为了避免这一切的内存头痛,通常建议使用STL容器,如std::vector,容器会照顾的内存管理的你,你的情况:

typedef std::vector<int> intvector; 
typedef std::vector<intvector> intintvector; 

void step1(intintvector &Data, ...) { 
    ... 
    // create data arrays 
    intvector data0, data1, data2, data3; 
    // fill data0, data1, data2, data3 
    // ... 
    // save data arrays. 
    Data.push_back(data0); 
    Data.push_back(data1); 
    Data.push_back(data2); 
    Data.push_back(data3); 
} 

void step2(const intintvector &savedData, ...) { 

    // read data arrays 
    intvector data0 = savedData[0]; 
    intvector data1 = savedData[1]; 
    intvector data2 = savedData[2]; 
    intvector data3 = savedData[3]; 
    // ... 
} 

在小结:如果您不处理动态内存,则不能正确使用指针部分,因此,您必须解决此问题或委托给STL容器。

希望它有帮助! :D

0

我试过Vyktor的解决方案,但没有奏效。我终于使用普通ol数组(无STL /向量)并使用下面的代码从另一个父数组中保存/加载数组。

请注意,此方法被认为是“遗留”,因为您必须使用delete [] myArray语法手动取消分配阵列。

unsigned int** step1(...) { 

    ... 

    // save data arrays 
    unsigned int** savedData = new unsigned int*[4]; // ** means pointer to a pointer 
    savedData[0] = data0; // transfer the pointer value straight 
    savedData[1] = data1; 
    savedData[2] = data2; 
    savedData[3] = data3; 
    return savedData; 
} 

unsigned char* step2(unsigned int** savedData, ...) { /// input is pointer to pointer 

    // read data arrays 
    unsigned int* data0 = savedData[0]; // read pointer straight 
    unsigned int* data1 = savedData[1]; 
    unsigned int* data2 = savedData[2]; 
    unsigned int* data3 = savedData[3]; 

    ... 

}