如何使用 malloc 从函数到 return C 字符串

How to use malloc to return C string from function

我正在尝试 return 来自函数的 C 字符串。该函数假设用逗号连接 3 个整数,return 结果作为 char 数组,但是我得到的是垃圾值。我假设我没有正确调用 malloc。有人可以就问题所在提出建议吗?

using namespace std;

const char * createCommand(int p1, int p2, int p3){
    stringstream sstm;
    std::string comma = ",";
    sstm << p1 << comma << p2 << comma << p3;
    std::string str = sstm.str();
    const char *cstr = (const char *)malloc( (str.length()+1) * sizeof (char));

    cstr = str.c_str();
    return cstr;    
}

int main() {
    const char *cstr2 = createCommand(1,0,250); //I want to return "1,0,250"
    printf("char = %s\n",cstr2);
}

在返回指针之前,您需要使用某种形式的 strcpy 复制字符串。

const char * createCommand(int p1, int p2, int p3){
    stringstream sstm;
    std::string comma = ",";
    sstm << p1 << comma << p2 << comma << p3;
    std::string str = sstm.str();
    const char *cstr = (const char *)malloc( (str.length()+1) * sizeof (char));

    strcpy(cstr, str.c_str());
    return cstr;    
}

赋值运算符,对 std::string 和其他对象工作良好,不能覆盖指针。因此,赋值

cstr = str.c_str();

泄漏您分配的内存,并用字符串中的数据替换指针。此外,您的函数 returns 现在指向的内存在退出函数时无效,除了泄漏之外还会产生未定义的行为。

要解决此问题,请调用 std::strcpy(cstr, str.c_str()); 不要忘记对调用结果调用 std::free编辑: 您应该从 createCommand 函数的 return 类型中删除 const(WhozCraig,谢谢您的评论)。

注意: 我假设这只是使用 malloc 的练习,您知道使用 new[] 更可取,并且您不会如果可以 return std::string 从函数中进行,则不必执行上述任何操作。

由于其他两个答案已经给出了处理字面问题的回应,我将建议我认为是导致您的问题的一个非常重要的设计缺陷:返回 c-strings。

在您提供的示例代码中,c-strings 的使用完全没有意义。以下代码将毫无困难或有问题地实现您打算做的事情:

std::string createCommand(int p1, int p2, int p3){
    std::stringstream sstm;
    std::string comma = ",";
    sstm << p1 << comma << p2 << comma << p3;
    return sstm.str();
}

int main() {
    std::string command = createCommand(1,0,250); //I want to return "1,0,250"
    std::cout << "char = " << command << "\n";
}

即使您局限于使用 printf 而不是 C++ iostreams 库,这种设计仍然更好:

std::string createCommand(int p1, int p2, int p3){
    std::stringstream sstm;
    std::string comma = ",";
    sstm << p1 << comma << p2 << comma << p3;
    return sstm.str();
}

int main() {
    std::string command = createCommand(1,0,250); //I want to return "1,0,250"
    printf("char = %s\n", command.c_str());
}

并且如果您需要将 c-string 传递给一些较旧的 C-based 库,此设计仍然足够。关键是,除了通过字符串本身之外,没有理由使用 malloc 或与底层 c-string 表示接口。