[英]Trying to pass 2D array of chars, but getting garbage
我正在嘗試解析std::string
,將其拆分,然后將其存儲在2D char數組中。 該數組的第一行將包含總行數。 我在getC_strings()
函數內部動態分配了數組,當我打印它時,得到了預期的結果。 但是,當我再次從main()
打印時,對於行0、2,我得到了垃圾,我在做什么錯呢?
#include <iostream>
#include <string>
#include <vector>
#include <boost/algorithm/string/classification.hpp> // Include boost::for is_any_of
#include <boost/algorithm/string/split.hpp> // Include for boost::split
using namespace std;
/**
*
* @param input a string separated by spaces
* @param numArgs_ an int
* @param cargs a const char ** something. Pass it by its address aka &something.
*/
static inline void getC_strings(const std::string & input, int & numArgs_, const char *** cargs) {
std::vector<std::string> args;
boost::split(args, input, boost::is_any_of(" "), boost::token_compress_on);
numArgs_ = int(args.size());
*cargs = new const char* [numArgs_ + 1];
// store the number of rows at the first row
(*cargs)[0] = new char[to_string(numArgs_).size()];
(*cargs)[0] = to_string(numArgs_).c_str();
// write the characters from the vector per row
int ind = 0;
for(auto const &v:args) {
ind++;
(*cargs)[ind] = new char [int(v.size())];
if((*cargs)[ind] == NULL) std::cout << "OUT OF MEMORY! " << std::endl;
(*cargs)[ind] = const_cast<char*>(v.c_str());
}
for(int i = 0; i < numArgs_; ++i) {
std::cout << i << " " << (*cargs)[i] << std::endl;
}
}
int main () {
string arg = "test ./MyDirectoryName/OPQ_Arksoatn.txt 1 SOMETHING 1 2 3 4 5 6 7";
int numCargs = 0;
const char ** cargs;
getC_strings(arg, numCargs, &cargs);
cout << " ==============================================" << endl;
for(int i = 0; i < numCargs; ++i) {
std::cout << i << " " << cargs[i] << std::endl;
}
return 0;
}
OUTPUT:
0 11
1 test
2 ./MyDirectoryName/OPQ_Arksoatn.txt
3 1
4 SOMETHING
5 1
6 2
7 3
8 4
9 5
10 6
==============================================
0 ��`
1 test
2 `��
3 1
4 SOMETHING
5 1
6 2
7 3
8 4
9 5
10 6
您可以嘗試這種不會泄漏內存的方法。 它是根據此處找到的解決方案制作的。
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <boost/algorithm/string/classification.hpp> // Include boost::for is_any_of
#include <boost/algorithm/string/split.hpp> // Include for boost::split
using namespace std;
class CharStarWrapper
{
private:
typedef std::vector<char> CharArray;
typedef std::list<CharArray> StringList;
typedef std::vector<const char *> ArgList;
const char** m_Args;
StringList m_sList;
ArgList m_cStrings;
public:
CharStarWrapper(const std::string & input) : m_Args(nullptr)
{
std::vector<std::string> args;
boost::split(args, input, boost::is_any_of(" "), boost::token_compress_on);
for (auto const &v : args)
{
// create an array of char and place on list
m_sList.push_back(CharArray(v.begin(), v.end()));
// null terminate this entry
m_sList.back().push_back(0);
// add the pointer to this entry to the vector of const char *.
m_cStrings.push_back(&m_sList.back()[0]);
}
m_Args = m_cStrings.data();
}
const char** getArgs() { return m_Args; }
int getArgCount() const { return static_cast<int>(m_cStrings.size()); }
};
void fake_main(int argc, const char **argv)
{
std::cout << "The number of arguments is " << argc << "\n";
for (int i = 0; i < argc; ++i)
std::cout << argv[i] << "\n";
}
int main() {
string arg = "test ./MyDirectoryName/OPQ_Arksoatn.txt 1 SOMETHING 1 2 3 4 5 6 7";
CharStarWrapper wrapper(arg);
fake_main(wrapper.getArgCount(), wrapper.getArgs());
}
基本上,我們將const char**
包裝在一個類中。 此類維護字符串的動態數組,並且僅提供public
成員函數以返回const char**
以及參數的數量。 調用“假” main()
函數演示了用法。
沒有對new[]
, delete[]
, strdup
等的調用,這些調用需要對釋放例程進行調用以避免內存泄漏。 當包裝超出范圍時,將自動清除所有內存。
請注意,此解決方案依賴於包裝對象在使用const char **
值的生命周期內不會超出范圍。 原因是CharStarWrapper
維護基礎結構,並且在使用基礎結構時將其破壞是不正確的。
在幾個地方:
// store the number of rows at the first row
(*cargs)[0] = new char[to_string(numArgs_).size()];
(*cargs)[0] = to_string(numArgs_).c_str();
和
// Similar code that allocates then ignores some space
(*cargs)[ind] = const_cast<char*>(v.c_str());
您正在執行一個指向std :: string內部部分的指針。 您需要將其復制到數組中,才能在char數組結構中使用它。 (請參閱strdup)。
用。。。來代替:
(*cargs)[0] = strdup(to_string(numArgs_).c_str());
和
(*cargs)[ind] = strdup(v.c_str());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.