4. 返回值是指针的情况
返回值显然是传出的而不是传入的,如果返回值传出的是指针,和上一节通过参数传出指针类似,也分为两种情况:第一种是传出指向静态内存或已分配的动态内存的指针,例如localtime(3)
和inet_ntoa(3)
,第二种是在函数中动态分配内存并传出指向这块内存的指针,例如malloc(3)
,这种情况通常还要实现一个释放内存的函数,所以有和malloc(3)
对应的free(3)
。由于这两种情况的函数接口相同,应该在文档中说明是哪一种情况。
表 24.5. 返回指向已分配内存的指针示例:unit_t *func(void);
调用者 | 实现者 |
---|---|
|
|
以下是一个完整的例子。
例 24.5. 返回指向已分配内存的指针
- /* ret_ptr.h */
- #ifndef RET_PTR_H
- #define RET_PTR_H
- extern char *get_a_day(int idx);
- #endif
- /* ret_ptr.c */
- #include <string.h>
- #include "ret_ptr.h"
- static const char *msg[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday"};
- char *get_a_day(int idx)
- {
- static char buf[20];
- strcpy(buf, msg[idx]);
- return buf;
- }
- /* main.c */
- #include <stdio.h>
- #include "ret_ptr.h"
- int main(void)
- {
- printf("%s %s\n", get_a_day(0), get_a_day(1));
- return 0;
- }
这个程序的运行结果是Sunday Monday
吗?请读者自己分析一下。
表 24.6. 动态分配内存并返回指针示例:unit_t *alloc_unit(void);
void free_unit(unit_t *p)
;
调用者 | 实现者 |
---|---|
|
|
以下是一个完整的例子。
例 24.6. 动态分配内存并返回指针
- /* ret_allocator.h */
- #ifndef RET_ALLOCATOR_H
- #define RET_ALLOCATOR_H
- typedef struct {
- int number;
- char *msg;
- } unit_t;
- extern unit_t *alloc_unit(void);
- extern void free_unit(unit_t *);
- #endif
- /* ret_allocator.c */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include "ret_allocator.h"
- unit_t *alloc_unit(void)
- {
- unit_t *p = malloc(sizeof(unit_t));
- if(p == NULL) {
- printf("out of memory\n");
- exit(1);
- }
- p->number = 3;
- p->msg = malloc(20);
- strcpy(p->msg, "Hello world!");
- return p;
- }
- void free_unit(unit_t *p)
- {
- free(p->msg);
- free(p);
- }
- /* main.c */
- #include <stdio.h>
- #include "ret_allocator.h"
- int main(void)
- {
- unit_t *p = alloc_unit();
- printf("number: %d\nmsg: %s\n", p->number, p->msg);
- free_unit(p);
- p = NULL;
- return 0;
- }
思考一下,通过参数分配内存需要两层的指针,而通过返回值分配内存就只需要返回一层的指针,为什么?