考慮代碼:
using std::cout; using std::cerr;
using std::endl; using std::string;
using std::vector;
// . . .
char* envp[10];
vector<string> lines;
char* c_line = nullptr;
size_t len = 0;
while ((getline(&c_line, &len, input_file)) != -1) {
string line;
lines.push_back(line.assign(c_line));
}
fclose(input_file);
free(c_line);
sprintf(envp[0], "SERVER=%s", lines[0].data());
// printing envp[0] here OK
sprintf(envp[1], "DOMAIN=%s", lines[1].data());
// printing envp[1] never happened - Segmentation fault prints in output instead
我是 C# 開發人員,我已經有幾十年沒用過 C 了。缺少一些明顯的東西。記憶體分配?
PS 我正在將字串的“舊”字符 * 與 std 字串混合,因為應用程式使用帶有字符的 3rd 方 dll *
char envp[10][512];當我嘗試使用 3rd 方屬性時,somedllObj.envps = envp;編輯宣告失敗cannot convert char[10][512] to char**
uj5u.com熱心網友回復:
我不建議std::string以這種狂野的方式混合和舊的 C 弦。相反,我會盡可能長時間地依賴 C 類:
std::ifstream inputFile("path to file");
if(!inputFile)
{
// error handling
}
std::vector<std::string> lines;
std::string tmp;
while(std::getline(inputFile, tmp))
{
lines.emplace_back(std::move(tmp)); // since C 11, not copying the strings...
}
if(!inputFile.eof())
{
// not the entire file read
// -> error handling!
}
// TODO: size check; what, if not sufficient lines in file?
lines[0] = std::string("SERVER=") lines[0];
lines[1] = std::string("DOMAIN=") lines[1];
std::vector<char*> envp;
envp.reserve(lines.size());
for(auto& l : lines) // C 11: range based for loop...
{
// note that this ABSOLUTELY requires the library not
// modifying the strings, otherwise undefined behaviour!
envp.emplace_back(const_cast<char*>(l.c_str()));
// UPDATE: this works as well:
envp.emplace_back(l.data());
// the string is allowed to be modified, too – apart from
// the terminating null character (undefined behaviour!)
}
// so far, pure C ...
// now we just get the pointers out of the vector:
libraryFunction(envp.size(), envp.data());
獎勵:根本沒有手動記憶體管理......
(注意:假設庫中的字串沒有被修改!)
uj5u.com熱心網友回復:
假設服務器和域在輸入檔案中,它們沒有空格,因此不需要 getline。
vector<string> lines;
std::ifstream input_file("path to file");
std::copy(std::istream_iterator<std::string>(input_file),
std::istream_iterator<std::string>(),
std::back_inserter(lines));
lines[0] = "SERVER="s lines[0];
lines[1] = "DOMAIN="s lines[1];
std::vector<char*> envp;
for(auto& line : lines)
envp.emplace_back(line.data());
envp.emplace_back(nullptr); // Usually env arrays end with nullptr, thus 1 to array size
somedllObj.envps = envp.data();
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/446314.html
