如何传个参数在函数里面申请内存,并返回这个内存的指针?

问题:如何传个参数在函数里面申请内存,并返回这个内存的指针?


void GetMemory(char* buff,int size){
    buff = (char*)malloc(sizeof(char) * size);
} 
这样能行吗?好像不行,为什么不行呢?
首先我们要弄清楚指针是什么,在计算机科学中,指针(英语:Pointer),是编程语言中的一类数据类型及其对象或变量,用来表示或存储一个存储器地址,这个地址的值直接指向(points to)存在该地址的对象的值。
我的理解是,在32位的系统中指针就是4字节的寻址数据,在64位系统中则是8字节的寻址数据。计算机通过寻址数据(指针)来找到存在在系统中的数据。至于数据找到了,怎么解释这段数据,这段数据块有多大这由指针的类型来决定。比如说int*类型,那系统就知道包括地址起始位置的sizeof(int)字节都是我们的寻址内容。所以我们对于void类型的指针p是无法通过类似p->data来访问他的数据成员的,因为系统不知道这个块有多大。
知道指针的概念后,我还有个问题:


void modify(int a){
   a = 1;
}
int a = 2;
modify(a);
printf("%d\n",a); 

上面的情况会printf的输出是2,这个应该大家都知道,因为是传值。也就是说,当你将a传入到modify中时,它相当于变成了如下:

void modify(int a){
   int temp = a;
   temp = 1;
} 

也就是说通过modify的处理并没有对a本身的值有任何影响。
现在我们再回到原来的问题,看看能通过上面的函数申请内存,并成功返回内存的指针吗?函数将变成如下形式:

void GetMemory(char* buff,int size){
    char* temp = buff;
    temp = (char*)malloc(sizeof(char) * size);
} 

也许你可能看出来了,我们再GetMemory中修改的只是temp的寻址数据,也就是只是修改了temp的指向,让temp指向了我们新申请的一个内存,然而我们的buff任然是原来的寻址数据,他的指向是不变的(其实modify中如果你知道如何改变a的值,那么这里其实你已经知道如果完成这个函数设计了)。为了更加清晰的分析,下面我假设在32位系统上,buff是个指针(寻址数据),我假设buff现在的寻址数据是0x00400001,buff作为计算机数据,他本身的4字节也需要地址空间来存放,存放在地址0x00500001上。

尴尬的使用word作图,真牛逼。
未malloc申请内存之前,buff和temp的指向如下:

beforemalloc.jpg
malloc申请内存以后,buff和temp的指向如下:

aftermalloc.jpg

那么如何才能做到函数内申请内存并返回呢?答案是指针的指针。
函数如下:

void GetMemory(char** buff,int size){
    *buff = (char*)malloc(sizeof(char) * size);
}
//转换后的函数
    void GetMemory(char** buff,int size){
    char** temp = buff;
    *temp = (char*)malloc(sizeof(char) * size);
} 

未malloc申请内存之前,buff和temp的指向如下:

ppbefore.jpg

malloc申请内存以后,buff和temp的指向如下:

ppafter.jpg

注:temp和buff指向同一个地址,即temp != buff ,but *temp == *buff

源码如下:
#include<iostream>
using namespace std;
//不考虑内存泄漏,让他疯狂漏
void GetMemory1(char *buff, int size) {
    printf("buff's addr in GetMemory1:%p\n", &buff);
    buff = (char*)malloc(sizeof(char) * size);
    if (buff) {
        printf("GetMemory1 buff malloc successfully! value of buff:%p\n",buff);
    }
    else {
        printf("GetMemory1 buff malloc failed!\n");
    }
}
void GetMemory2(char **buff, int size) {
    printf("buff's addr in GetMemory2: %p\n", buff);
    *buff = (char*)malloc(sizeof(char) * size);
    printf("*buff's addr in GetMemory2: %p\n", *buff);
    if (*buff) {
        printf("GetMemory2 buff malloc successfully!\n");
    }
    else {
        printf("GetMemory2 buff malloc successfully!\n");
    }
}
int main() {
    char* buff = (char*)malloc(sizeof(char));
    printf("buff's addr before GetMemory1 :%p\n", buff);
    GetMemory1(buff, 10);
    printf("buff's addr after GetMemory1 :%p\n", buff);
    printf("-------------------------------\n");
    GetMemory2(&buff, 10);
    printf("buff's addr after GetMemory2 :%p\n", buff);
    getchar();
    return 0;
}

运行结果如下:

result.jpg

有什么不懂的可以跑下程序,打印出来看看或者提出来问问。

全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务