编写C函数的正确方法是什么?返回char数组?

时间:2011-11-29 13:00:12

标签: c string dynamic-allocation

我对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数组,然后将其传入。

处理这种情况的正确方法是什么?

5 个答案:

答案 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;
}