c++ - 试图传递二维字符数组,但得到垃圾

标签 c++ arrays

我正在尝试解析一个 std::string,拆分它,然后将它存储在一个二维字符数组中。该数组的第一行将包含总行数。 我在 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;
}

输出:

    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

最佳答案

你可以试试这个不泄漏内存的方法。它由溶液 found here 制成.

#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());        
}

Live Example

基本上,我们将 const char** 包装在一个类中。该类维护动态字符串数组,仅提供public 成员函数返回const char** 以及参数个数。对“假”main() 函数的调用演示了用法。

没有调用 new[]delete[]strdup 等需要调用释放例程避免内存泄漏。当包装器超出范围时,所有内存都会自动清理。

请注意,此解决方案依赖于在您将使用 const char ** 值的生命周期内不超出范围的包装对象。原因是 CharStarWrapper 维护基础设施,在使用它的同时破坏基础设施是不正确的。

关于c++ - 试图传递二维字符数组,但得到垃圾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42846490/

相关文章:

c++ - 将 exe 转换为 DLL - 手动调用主函数

c++ - 当高度小于边界半径的两倍时保持圆 Angular ?

具有动态名称的 PHP 方法链接

arrays - 在伪代码中使用 'temp'

c++ - 在哪里定义编译时常量?

c++ - 核心文件的大小是否反射(reflect)了应用程序崩溃时的内存使用情况?

c++ - 打印在 Visual Studio 2008 Windows 窗体应用程序中不起作用

Javascript,检查数组和周围的节点

JavaScript 将数组插入数组

c++ - 在运行时设置数组维度