返回指针很容易,只要返回的类型是某种数据类型的指针即可。从函数返回对象时经常用到以下两种技术。
- 使用
malloc
在函数内部分配内存并返回其地址。调用者负责释放返回的内存。 - 传递一个对象给函数并让函数修改它。这样分配和释放对象的内存都是调用者的责任。
首先,我们介绍用malloc
这类函数来分配返回的内存,随后的示例中我们返回一个局部对象的指针,不推荐后一种方法。上面列出的第二种技术在3.2.6节中说明。
在下面的例子中,我们定义一个函数,为其传递一个整数数组的长度和一个值来初始化每个元素。函数为整数数组分配内存,用传入的值进行初始化,然后返回数组地址:
int* allocateArray(int size, int value) {
int* arr = (int*)malloc(size * sizeof(int));
for(int i=0; i<size; i++) {
arr[i] = value;
}
return arr;
}
下面说明如何使用这个函数:
int* vector = allocateArray(5,45);
for(int i=0; i<5; i++) {
printf("%d\n", vector[i]);
}
图3-5说明了这个函数的内存分配。左图显示return
语句执行前的程序状态,右图显示函数返回后的程序状态。vector
变量包含了函数内分配的内存的地址。当函数终止时arr
变量也会消失,但是指针所引用的内存还在,这部分内存最终需要释放。
尽管上例可以正确工作,但从函数返回指针时可能存在几个潜在的问题,包括:
- 返回未初始化的指针;
- 返回指向无效地址的指针;
- 返回局部变量的指针;
- 返回指针但是没有释放内存。
最后一个问题的典型代表就是allocateArray
函数。从函数返回动态分配的内存意味着函数的调用者有责任释放内存。看一下这个例子:
int* vector = allocateArray(5,45);
...
free(vector);
最终我们必须在用完后释放内存,否则就会产生内存泄漏。