2011-02-03 47 views
1

我可以返回一个在函数内部动态创建的数组(使用malloc)给它的调用者吗?从函数中返回一个字符数组c

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

+0

可以返回一个指针,还是有更复杂的东西,你脑子里想的? – Swiss 2011-02-03 01:45:41

+3

静态分配!=自动分配。局部变量具有自动存储时间。静态存储持续时间意味着对象在程序运行的整个过程中都存在(这些对象在文件作用域或在函数中使用`static`声明)。 – 2011-02-03 01:47:38

回答

5

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

0

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

但是,调用者需要了解它需要在某个时间点被释放,否则您将发生内存泄漏。

0

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

3

正如其他人已经指出的,你实际上可以返回一个字符指针。 但是,另一种常见的方法是让调用者传入方法的指针以填充长度参数。这使得它负责分配内存的功能也将是负责释放内存的相同功能,这可以使内存泄漏更容易看到。这是什么功能,如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); 
}