从c中的函数返回一个字符数组

时间:2011-02-03 01:43:44

标签: c

我可以将函数内动态创建的数组(使用malloc)返回给调用者吗?

我知道返回一个静态分配的数组是错误的,因为当函数返回并且变量不再有效时,堆栈会展开,但是动态分配的变量呢?

4 个答案:

答案 0 :(得分:5)

返回任何使用malloc分配的东西都没问题,只要使用你的函数的人在完成后就可以自由地使用它。 malloc在堆上分配,这在您的程序中基本上是全局的。

答案 1 :(得分:3)

正如其他人所说,你实际上可以返回一个char指针。 但是,另一种常见的方法是调用者传入指针以便方法填充长度参数。这使得负责分配内存的功能也是负责释放内存的功能,这可以使内存泄漏更容易看到。这就是snprintfstrncpy等功能。

/* Performs a reverse strcpy. Returns number of bytes written if dst is
 * large enough, or the negative number of bytes that would have been
 * written if dst is too small too hold the copy. */
int rev_strcpy(char *dst, const char *src, unsigned int dst_len) {
    unsigned int src_len = strlen(src); /* assumes src is in fact NULL-terminated */
    int i,j;

    if (src_len+1 > dst_len) {
        return -(src_len+1);  /* +1 for terminating NULL */
    }

    i = 0;
    j = src_len-1;
    while (i < src_len) {
        dst[i] = src[j];
        ++i;
        ++j;
    }
    dst[src_len] = '\0';

    return src_len;
}

void random_function() {
    unsigned int buf_len;
    char *buf;
    int len;
    const char *str = "abcdefg";

    buf_len = 4;
    buf = malloc(buf_len * sizeof(char));
    if (!buf) {
        /* fail hard, log, whatever you want */
        return;
    }

    /* ...whatever randomness this function needs to do */

    len = rev_strcpy(buf, str, buf_len);
    if (len < 0) {
        /* realloc buf to be large enough and try again */
        free(buf);
        buf_len = -len;
        buf = malloc(buf_len * sizeof(buf));
        if (!buf) {
            /* fail hard, log, whatever you want */
            return;
        }
        len = rev_strcpy(buf, str, sizeof(buf));
    }

    /* ... the rest of the randomness this function needs to do */

    /* random_function has allocated the memory, random_function frees the memory */
    free(buf); 
}

如果您不知道需要多大的缓冲区并且需要两次调用该函数,这可能会导致一些开销,但通常调用者知道缓冲区需要多大。此外,它需要更多的逻辑来确保函数不会超出给定的缓冲区。但它保留了释放内存的责任,同时还允许选项传递本地堆栈内存。

返回char*

的示例
/* Performs a reverse strcpy. Returns char buffer holding reverse copy of
 * src, or NULL if memory could not be allocated. Caller is responsible
 * to free memory. */
char* rev_strcpy(const char *src) {
    unsigned int src_len = strlen(src); /* assumes src is in fact NULL-terminated */
    char *dst;
    int i,j;

    dst = malloc((src_len+1) * sizeof(char));
    if (!dst) {
        return NULL;
    }

    i = 0;
    j = src_len-1;
    while (i < src_len) {
        dst[i] = src[j];
        ++i;
        ++j;
    }
    dst[src_len] = '\0';

    return dst;
}

void random_function() {
    char *buf;
    const char *str = "abcdefg";

    /* ...whatever randomness this function needs to do */

    buf = rev_strcpy(str);        
    if (!buf) {
        /* fail hard, log, whatever you want */
        return;
    }

    /* ... the rest of the randomness this function needs to do */

    /* random_function frees the memory that was allocated by rev_strcpy */
    free(buf); 
}

答案 2 :(得分:0)

是的,你可以。只需malloc()函数内的数组并返回指针。

但是,调用者需要了解它需要在某个时候被释放,否则你会有内存泄漏。

答案 3 :(得分:0)

你当然可以返回一个用malloc分配的数组,但你必须确保函数的调用者最终用free释放数组;如果你没有释放malloc'd数组,那么在程序退出之前,内存仍然处于“使用中”状态。