当我为给定的函数删除b的内存" lowerCaseWord(char * a)"?我需要返回b的值,所以我不能在行之前删除它"返回b;"。我需要使用另一个变量吗?或者编译器是否单独删除它(即使它不是很好的编程)?
char* lowerCaseWord(char* a)
{
char *b=new char[strlen(a)];
for (int i = 0; i < strlen(a); i++)
{
b[i] = tolower(a[i]);
}
return b;
}
答案 0 :(得分:2)
你需要自己delete[]
以外的功能,即使这不是一个好习惯。如:
char* rtv = lowerCaseWord(a);
// process with rtv
// ...
delete[] rtv;
最好使用smart pointer来避免手动内存管理,例如:
std::unique_ptr<char[]> lowerCaseWord(char* a)
{
...
}
然后
std::unique_ptr<char[]> rtv = lowerCaseWord(a);
// process with rtv
// ...
正如@FrerichRaabe指出的那样,基本上使用原始指针不是一个好主意,你可能想直接使用std::string
。
答案 1 :(得分:2)
对于初学者来说,这个功能是错误的
char* lowerCaseWord(char* a)
^^^^
{
char *b=new char[strlen(a)];
^^^^^^^^^
for (int i = 0; i < strlen(a); i++)
^^^
{
b[i] = tolower(a[i]);
^^^^
}
return b;
}
它获取一个字符串但不返回字符串,因为新的字符数组不包含终止零。
它不能处理常量对象,例如字符串文字。而且它会让用户感到困惑,因为他们会认为他们的原始字符串在函数中已经改变了。
标准函数tolower
也会考虑将字符转换为unsigned char
。
这是根据C标准(7.4字符处理)
- ...在所有情况下,参数都是一个int,其值应为 可表示为 unsigned char 或等于该值 宏观EOF。如果参数有任何其他值,行为是 未定义即可。
醇>
变量i
的类型应该是size_t
,因为iit是具有函数strlen
的返回值的类型。
你必须写
char* lowerCaseWord( const char *a )
{
char *b = new char[std::strlen( a ) + 1];
size_t i = 0;
do
{
b[i] = std::tolower( static_cast<unsigned char>( a[i] ) );
} while ( a[i++] );
return b;
}
函数设计假设它是函数的客户端必须释放返回指针所指向的内存。
答案 2 :(得分:1)
您的示例代码确实是C ++代码,但它不是正版 C ++代码。
最近的C ++ 11(或C ++ 14)倾向于不鼓励编写这样的东西。您可能希望使用smart pointers,RAII习语,rule of five,std::string
- s,
当然,在进行显式手动内存分配的语言和程序中,您需要约定和规则来定义指针的发布时间和时间。使用您的代码,您至少需要在头文件中添加注释,说明应该释放lowerCaseWord
函数的结果的方式和时间。
我相信你至少应该阅读有关garbage collection和reference counting的内容(至少在概念和术语方面)。
答案 3 :(得分:1)
智能指针是一种解决方案,但我建议将您的功能更改为:
void lowerCaseWord(char* destination, const char* source);
使用此定义,调用者负责为目标字符串分配和释放内存。这样做的好处是目标可以位于堆栈上,堆上,甚至是类/结构的成员。如果内存总是由函数分配,则无法进行此操作。
strcpy
和朋友也是这样定义的。