2011-08-22 54 views
0

可能重複:
std::vector<std::string> to char* array如何從C++字符串的指針的dymamic數組傳遞到C函數

我必須調用接受字符串指針陣列的C函數。示例

void cFunction(char* cities[], int count) 
{ 
    for(int i = 0; i < count; ++i) 
    { 
    printf("%s\n", cities[i]); 
    } 
} 

假設函數在某個第三方的libabry中;它不能改變
我可以聲明一個靜態數組,並調用函數這樣

char* placesA[] = {"Teakettle Junction", "Assawoman Bay", "Land O' Lakes", "Ion", "Rabbit Hask" }; 
cFunction(placesA, 5); 


工程。但是我的數據是動態的,即數組的大小在運行時改變了很多次
所以,我想這個

std::vector<std::string> placesB(placesA, placesA + 5); 
cFunction(&placesB[0], 5); // this won't work because std::string != char*[] 


試過這種

std::vector<char*> placesC; 
cFunction(&placesC[0], 5); 

我覺得placesC尷尬的填充同時避免內存泄漏
我正在尋找一個既高效的解決方案(儘可能少的字符串複製,最好使用STL和或Boost)

+0

@Bertrand馬龍不是重複。我的源數據不一定是std :: string。我使用std :: vector 作爲解決方案中的一個可能的中間步驟 – cabralP

回答

1

無論你如何切片,都會有一些尷尬。如果C API確實需要可修改的數組,那麼這就是你需要提供的 - 你必須複製你的字符串。如果它不修改字符串,那麼可以使用的const char*,其中字符串數據仍屬於底層的std::string對象;您只需要小心C API不會保留對這些字符串的引用,並在字符串被修改或釋放後嘗試訪問它們。

例如,這是應該做的一種方式:

// Unary functor which calls c_str() on a std::string object 
struct StdStringCStrFunctor 
{ 
    const char *operator() (const std::string& str) { return str.c_str(); } 
}; 
... 

std::vector<std::string> places; 
... // populate places 

// Convert to array of C strings 
std::vector<const char *> placesCStr(places.size()); 
std::transform(places.begin(), places.end(), placesCStr.begin(), StdStringCStrFunctor()); 
cFunction(const_cast<char**>(&placesCStr[0]), placesCStr.size()); 
+0

這看起來很整齊。讓我做一些測試 – cabralP

+0

只是好奇,如果沒有內存泄漏在這裏。誰刪除placesCStr中的char * s – cabralP

3

您可以在每個字符串上使用.c_str()編寫一個函數,該函數使用vector<string>填充vector<char*>

+0

然後您可以將'&charvec [0]'傳遞給'cFunction()'。 – wilx

+0

這需要一個'const_cast',但在被調用者的網站上有點謹慎,這是可行的。 –

+1

使用'&the_string [0]'不需要'const_cast'(假設該矢量的非常量視圖),但需要C++ 0x,因爲C++ 03不能保證' std :: basic_string'在內存中是連續的。 –

相關問題