假设我想动态分配内存,但使用函数而不是main((函数。
所以我尝试这样做:
dynamAlloc(int *fPtr)
{
fPtr=malloc(cols * sizeof(*fPtr) );
if(fPtr==NULL)
{
printf("Can't allocate memory");
exit(1);
}
}
然后我意识到:即使堆上分配的内存在程序的生命周期内可用,该内存也只能由形式参数fPtr
引用,而不能由实际参数引用(我们称之为aPtr
(。但是一旦函数退出,该内存就会丢失。
那么如何使用函数动态分配内存呢?
只能由形式参数
fPtr
引用,而不能由实际参数引用(我们称之为aPtr
(。
aPtr
无法在调用dynamAlloc()
之前向堆内存对象表示,因为尚未分配该对象,并且其地址分配给aPtr
槽fPtr
。此后aPtr
引用堆对象。
我们只需要将aPtr
指针的地址传递给dynamAlloc()
。因此,您需要适当的参数(实际参数(和参数(形式参数(来传递指针的地址aPtr
函数,如下所示。
那么如何使用函数动态分配内存呢?
你这样做就像你main()
一样,不管指针是在main()
还是另一个函数内部声明的,你只需要将指针的地址aPtr
传递给其他函数,你想在其中使用堆内存对象,如 f.e.:
#include <stdio.h>
#include <stdlib.h>
#define cols 5
void dynamAlloc(int** fPtr);
int main()
{
int* aPtr;
dynamAlloc(&aPtr);
free(aPtr);
return 0;
}
void dynamAlloc(int** fPtr)
{
*fPtr = malloc(sizeof(*fPtr) * cols);
if(*fPtr == NULL)
{
printf("Can't allocate memory");
exit(1);
}
}
不要忘记free()
堆内存!
或者干脆这样:
void dynamAlloc(int **fPtr)
{
*fPtr=malloc(cols * sizeof(**fPtr) ); // malloc is returning void* so in that place it would be compiler error, so pointer returned from malloc should be casted to the pointer type of the value.
if(*fPtr==NULL) // that would be a warning in gcc since NULL is a macro eq to 0, or (void*)0, it compiler version
{
printf("Can't allocate memory");
exit(1);
}
}
和功能用法:
int* ptr = (int*)NULL;
dynamAlloc(&ptr);
*ptr = 1; // assign 1 to the first element, ptr is a valid pointer here
但是双指针语法在某些情况下可能会变慢,在最后回答 od 功能,复制该本地指针是更好的做法。
由于您需要更改指针本身 - 需要指针到指针
void *allocate(void **tmp, size_t size)
{
if(tmp)
{
*tmp = malloc(size);
}
return *tmp;
}
int main()
{
int *ptr;
if(!allocate((void**)&ptr, sizeof(*ptr) * 100))
{
perror("Errorn");
exit(1);
}
/* do something*/
free(ptr);
}
使用宏函数更方便,如下所示:
#include <stdio.h>
#include <stdlib.h>
#define NEW_ARRAY(ptr, n)
{
(ptr) = malloc((size_t) (n) * sizeof (ptr)[0]);
if ((ptr) == NULL) {
fputs("Can't allocate memoryn", stderr);
exit(EXIT_FAILURE);
}
}
#define NEW(ptr) NEW_ARRAY((ptr), 1)
int main(void)
{
int *myArray;
const int myArrayLen = 100;
int i;
NEW_ARRAY(myArray, myArrayLen);
for (i = 0; i < myArrayLen; i++) {
/*...*/
}
return 0;
}
更新:
宏的目的是抽象出细节,使内存分配不易出错。使用(非宏(函数,我们必须将元素大小作为参数传递,因为当指针传递到类型为 void 指针的形式参数时,该信息会丢失:
void NewArray(void *ptr, int n, int elemSize)
{
*ptr = malloc((size_t) n * sizeof elemSize);
if (*ptr == NULL) {
fputs("Can't allocate memoryn", stderr);
exit(EXIT_FAILURE);
}
}
使用函数NewArray,对应于第一个示例的分配调用变为
NewArray(&myArray, n, sizeof myArray[0]);
这给我们买的不多。