2017-02-10 140 views
-1

我想从函数返回一个C字符串。该函数假设用逗号分解3个整数,然后将结果作为char数组返回,但是我得到的是垃圾值。我假设我没有正确调用malloc。有人可以就这个问题提出建议吗?如何使用malloc从函数返回C字符串

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); 
} 
+0

你在这里漏了很多。 –

+0

您有*具有*返回c字符串的具体原因吗?除非你有很好的理由,否则你绝对不应该在C++中编写这样的代码。 – Xirema

+0

在C++中,您应该使用'new'而不是'malloc'来动态分配内存。 – Barmar

回答

2

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

在您提供的示例代码中,使用c字符串是毫无意义的。下面的代码将实现你打算与任何困难或有问题的代码做什么:

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++的iostream库,这个设计还是更好:

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字符串传递给一些较旧的基于C的库,则此设计仍然足够。重点是,没有理由使用malloc或与底层C字符串表示接口,除非通过字符串本身。

+0

所以你不必处理'command.c_str()'的malloc的原因是因为它在主要方法? – bakalolo

+0

不,这是因为'c_str()'只是返回一个指向'std :: string'拥有的内存的指针。 'std :: string'将为你解决这个问题。 –

+1

@bakalolo你不需要处理malloc的原因是因为'std :: string'对象管理自己的动态内存。你没有理由自己去做。 – Xirema

0

在返回指针之前,您需要复制某种形式的字符串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;  
} 
1

赋值运算符,这对于std::string和其他对象正常工作,不能有指针覆盖。因此,分配

cstr = str.c_str(); 

泄漏您分配的内存,并用字符串中的数据替换指针。而且,函数返回的指针现在指向退出函数时失效的内存,除了泄漏外,还会创建未定义的行为。

要解决此问题,请致电std::strcpy(cstr, str.c_str());请不要忘记致电std::free以了解有关呼叫的结果。 编辑:你应该从createCommand函数的返回类型中删除const(WhozCraig,感谢你的评论)。

注:我认为这只是在使用malloc练习,你知道,使用new[]最好,而且你不会做任何以上的,如果你可以从函数返回std::string

+0

我不会做任何假设。太多“C++程序员”是C程序员,他们认为C++只是“C类”,或者相同的设计原则适用于这两种语言。 – Xirema

+0

@Xirema根据OP的资料,它看起来并不像以前有很多C经验,所以我最好的猜测是这是一个学习练习。 – dasblinkenlight

+0

另外需要注意的一点是:OP的代码显示'createCommand'返回'const char *',这在返回'malloc'结果时没有任何意义,因为调用者缺少断裂常量,不能随意释放结果指针。这个答案的变化正是OP所需要的,但是另外,调用应该返回'char *',此时由调用者记住'free()'的建议变得可行。 – WhozCraig