编写一个返回char *?
的函数是否正确这样的事情:
char * func()
{
char *c = new char[3];
strcpy(c, "hi");
c[2] = '\0';
return c;
}
int main()
{
char *c;
c = func();
//code using c
delete [] c;
return 1;
}
它有效,但它是否正确?
答案 0 :(得分:6)
这是正确的(假设你的意思是strcpy
而不是strlen
),但是从函数的文档中必须非常清楚,调用者有责任释放返回的指针,以及使用什么方法是否必须使用它来释放它(new
=> delete
,new []
=> delete[]
,malloc
=> free
等)。这就是做到这一点的“C方式”。
这依赖于你的函数的用户(包括你在编写它几个月之后)阅读文档以使事情正确,因此它非常容易出错;另外,在C ++中,还有一些并不存在于C中的并发症(即:异常),这些并发症使得在这些上下文中使用原始指针并不是一个好主意。
这就是为什么你通常应该返回封装资源的类(例如在这种情况下为std::string
,以及通常自动管理内存的容器)或所有权转移智能指针的原因,这也是异常安全(您的代码不是)。
这听起来非常复杂,但实际上并非如此:
#include <string>
std::string func()
{
return "hi"; // actually, to be more explicit it should be return std::string("hi")
}
int main()
{
std::string c;
c=func();
return 1;
}
就是这样,无需担心分配/解除分配和异常,所有这些都由std::string
类自动处理,因此您可以管理字符串,就像它们内置类型一样。
答案 1 :(得分:2)
嗯,这很有效。内存在堆上分配并正确释放。由于strcpy
这样做,因此无需手动添加空终止符。
但它不是真正的C ++。在C ++中,您将使用std::string
。
答案 2 :(得分:2)
它有效,但它是否正确?
您的代码正确。
但是,它取决于上下文,如果它是一个很好的编程实践。对于您发布的这个最小程序,我不想使用new[]
和delete[]
。但宁可依赖std::string
。
答案 3 :(得分:1)
您的代码在技术上是正确的。但是,我认为大多数SO-ers对于它是否被认为是“好”代码有所保留。
首先:
c
和func
不是很具描述性,让其他人难以理解您的目标strncpy()
超过strcpy()
以防止意外的缓冲区溢出(或查看String类)答案 4 :(得分:0)
尝试:
char * func()
{
char * c = new char[3];
strcpy(c,"hi");
return c;
}
int main()
{
char *c;
c = func();
//code using c
delete [] c;
return 0;
}