我对Java非常熟悉,而在C中则不是这样。
在Java中,如果我有一个方法可以执行某些操作并返回一个String,它将如下所示:
private String doSomething(...) {
String s;
// do something;
return s;
}
C中的句法等价物不起作用,而且是完全错误的:
char* doSomething(...) {
char s[100];
// do something;
return s;
}
当然我能做到:
char* doSomething(...) {
char *s;
s = malloc(100 * sizeof(char));
// do something;
return s;
}
哪个会起作用(我想!)但我很少看到代码这样做(是因为它不必要地填满了堆?)
最常见的是,我看到了:
bool doSomething(char *s) {
// do something that copies chars to s
return true;
}
调用语句将是:
char s[100];
doSomething(s);
如果在函数本身内部之前我不知道char数组的大小怎么办?即我无法在函数外部声明char数组,然后将其传入。
处理这种情况的正确方法是什么?
答案 0 :(得分:19)
让调用代码负责分配内存。在示例2中传递缓冲区和缓冲区的长度:
bool doSomething(char *s, size_t buflen)
{
// do something that copies chars to s up to max of buflen
return true;
}
这会减少泄漏,因为调用代码控制着内存管理。
答案 1 :(得分:5)
静态分配案例(您必须考虑编译时的最大缓冲区大小)
buf[MAX_NO];
do(buf, MAX_NO);
_Bool do(char *s, size_t len) {
// use len as boundary in your operations
}
或动态分配案例(如你所说使用malloc并使用指针来保存缓冲区的位置和大小)
char *s = NULL;
size_t final_len;
do(&s, &final_len);
_Bool do(char** s, size_t* final_len) {
size_t len = discoverSize();
char* buf = (char*) malloc(sizeof(char) * len);
*s = buf; //save memory location
*final_len = len; //save buffer size
// use len as boundary in your operations
}
// do whatever
free(s); //remember to free the buffer for politeness
答案 2 :(得分:2)
如果您无法知道返回字符串的正确大小,请使用malloc
解决方案。当然,完成后你必须free
字符串。
答案 3 :(得分:1)
您无法在C中返回数组。
你可以返回一个指针,你应该学习(通过阅读 C 语言编程的好的书)数组之间的区别和指针。
常见的习惯用法是返回动态分配的指针。然后你应该有一个约定,告诉谁将释放指针。
您还可以返回包含数组的结构。
如果您想在C中安装垃圾收集器,请尝试Boehm's garbage collector
答案 4 :(得分:0)
最安全的方法是将责任分配给来电者,如其他人所说。
但是,如果你不需要可重入的代码和Java的简单性,那么C语法中的句法等效是:
char* doSomething(...) {
static char s[100];
// do something;
return s;
}