【问题标题】:Passing C++ String to C libraries for memory management将 C++ 字符串传递给 C 库以进行内存管理
【发布时间】:2019-02-25 23:13:42
【问题描述】:

我正在尝试使用 C 库,它要求我传入动态分配的 c 字符串以供函数修改。但是,我想避免使用 new/delete 运算符,因为我觉得由 STL 库而不是我自己完成内存管理是更好的做法。

下面,我尝试使用 std::string (和向量)来解决这个问题,并在将它们传递给 C 函数之前预先分配它们。带有一个字符串(CChar,CVoid)的示例可以工作,但我仍然不确定这是否是正确的方法,或者即使它是一种安全的方法(无错误)。使用向量似乎根本不起作用。

我已经包含了“C”方式来执行我想要为字符串和向量实现的目标。

#include <string>
#include <iostream>
#include <vector>

// ----------------------------------------------------
// Example C library Code
void CChar(char* data, int len)
{
    int i;
    for (i = 0; i < len; ++i)
        data[i] = 'A' + (i % 26);
}

void CVoid(void* data, int len)
{
    char* d = (char*)data;
    int i;
    for (i = 0; i < len; ++i)
        d[i] = 'Z' - (i % 26);
}

void CStrings(char** strings, int count, int lengths)
{
    int i, j; 
    for (i = 0; i < count; ++i)
        for (j = 0; j < lengths; ++j)
            strings[i][j] = 'A' + ((i * j + i) % 26);
}
// ----------------------------------------------------

// C++ code
int main()
{
    // Traditional way, using new/delete.
    char* c = new char[11];
    CChar(c, 10);
    c[10] = '\0';
    std::cout << c << std::endl; // ABCDEFGHIJ
    delete [] c;

    std::string s(10, '\0');
    CChar(&s[0], 10);

    std::cout << s << std::endl; // ABCDEFGHIJ
    CVoid(&s[0], 10);

    std::cout << s << std::endl; // ZYXWVUTSRQ
    std::vector<std::string> v(5, std::string(10, '\0'));

    // Traditional way with arrays of arrays.
    char** cc = new char*[5];
    for (int i = 0; i < 5; ++i)
    {
        cc[i] = new char[11];
        cc[i][10] = '\0';
    }
    CStrings(cc, 5, 10);
    for (int i = 0; i < 5; ++i)
    {
        std::cout << cc[i] << std::endl; // AAAAAAAAAA, BCDEFGHIJK, CEGIKMOQSU, DGJMPSVYBE, EIMQUYCGKO
        delete [] cc[i];
    }
    delete [] cc;      

    // Doesn't compile
    // CStrings(&v[0], 5, 10);

    // for (int i = 0; i < 5; ++i)
    //     std::cout << v[i] << std::endl;

    return 0;
}

总结:有没有好办法使用C++的STL库,这样我在尝试使用C库的时候就不需要自己做资源管理了。

编辑:清理数组时出错

【问题讨论】:

  • 你可以调用std::string.c_str()方法来获取一个string类的undelrying char数组传给你正在使用的c api。
  • @lorand:不,他说函数需要修改字符串——但是 c_str() 返回一个指向 const char 的指针。
  • 使用std::vector&lt;char&gt;,如果需要记得添加0
  • @PlinyTheElder 好点。我不知道。无论如何,一个hacky解决方案是使用const_cast&lt;char*&gt;(std::string::c_str())
  • const_cast-ing c_str 也可以,但看起来确实很老套。

标签: c++ c arrays string c-strings


【解决方案1】:

当然,如果你不想考虑分配,你可以使用std::vector&lt;char&gt;。以下是你的做法:

#include <vector>

int main()
{
    std::vector<char> str(100, 0); //Allocate an array of 100 chars and initialize them to 0

    SomeFunction(&str[0], str.size()); //Pass the address to the array and its size

    return 0;
}

【讨论】:

  • str.data()&amp;str[0]一样吗?
  • @Barmar:是的,但在 C++11 之前不可用。
  • &amp;str[0] 使用起来看起来很笨拙吗?我想当我使用 C 代码时,需要一定程度的 hackiness。
  • 这适用于单个字符串,我仍然不确定如何处理多个字符串。
  • @mojo:创建一个缓冲区向量数组。
【解决方案2】:

对于数组的数组,可以存储一个vector&lt;char*&gt;,它指的是已经动态分配的std::vector&lt;std::string&gt;的开始。

int main()
{
    std::vector<std::string> v(5, std::string(10, '\0'));
    std::vector<char*> vc(5);
    for (int i = 0; i < 5; ++i)
        vc[i] = &(v[i])[0];

    CStrings(&vc[0], 5, 10);

    for (int i = 0; i < 5; ++i)
        std::cout << v[i] << std::endl;

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 2015-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-26
    相关资源
    最近更新 更多