动态内存开辟3

动态内存开辟相关试题

我们此次会介绍关于动态内存开辟的一些试题,错误点,以及原因 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void getmemory(char* p)//p也是空指针
{
p = (char*)malloc(100);//在堆上开辟100个字节的空间,将这100个字节的起始地址交给了p,p便不再是空指针,但p只是个形式参数,
//出了函数便销毁了,使得malloc开辟的空间再也找不到了,内存泄露了
//内存泄露未free释放掉导致strcpy也无法执行,什么都没有
}
int main()
{
char* str = NULL;
getmemory(str);
strcpy(str, "hello world");//回来后str还是空指针,拷贝不成功
printf(str);
return 0;
}

 str是一个变量,str传给getmemory函数,是值传递,
所以getmemory函数的形参p是str的一份临时拷贝,在其内部动态申请空间的地址,存放在p中,
不会影响外边的str,所以当getmemory返回后,str仍然是个空指针,所以strcpy会失败
当getmemory函数返回后,形参p销毁i,使得动态开辟的100个字节存在内存泄露

修改1. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 char *getmemory(char* p)//p也是空指针
{
p = (char*)malloc(100);
return p;//p的类型是char*,所以getmemory中接收了malloc开辟的空间
}
int main()
{
char* str = NULL;
str=getmemory(str);//str接收了p里面的地址
strcpy(str, "hello world");
printf(str);//str就是一个字符指针因此str这样是可以用的
free(str);//使用完进行释放
str = NULL;//再将其制成空指针
return 0;
}

修改2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

void getmemory(char** p)//char**二级指针进行接收
{
*p = (char*)malloc(100);//p是&str,*p是str,
}
int main()
{
char* str = NULL;
getmemory(&str);//想让他改变这个str,就将str的地址传过去,str是个指针,&str是个二级指针
strcpy(str, "hello world");
printf(str);
free(str);
str = NULL;
return 0;
}

例2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
char*getmemory(void)//返回栈空间地址的问题,出返回就销毁了,而堆上开辟的空间出函数是不销毁的
{
char p[] = "hello world";//p是一个局部的数组,进入函数生命周期开始,出函数生命周期结束销毁释放,
return p;//p也是一个指针,所以返回类型是char*,p返回的是hello world的起始地址
}
void test(void)
{
char *str = NULL;
str = getmemory();//str存的是h首元素地址,接收后那个空间就还给操作系统了
printf(str);
}
int main()
{
test();
return 0;
}

getmemory函数内部创建的数组是在栈区开辟的
出了函数,p数组的空间就返回给了操作系统
返回的地址是没有实际意义,如果通过返回的地址,去访问内存就是非法访问内存的
char*getmemory(void)//返回栈空间地址的问题,出返回就销毁了,而堆上开辟的空间出函数是不销毁的

此类问题可以归结为返回栈空间的内容,一律是错误的

同类题如1,

1
2
3
4
5
int*f1(void)//同样是在栈区开辟的问题
{
int x = 10;
return(&x);//返回的是没有意义的
}

同类题2.

1
2
3
4
5
6
int*f2(void)
{
int* ptr;//归结为野指针
*ptr = 10;
return ptr;
}

例3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void getmemory(char**p, int num)
{
*p = (int*)malloc(num);
}

void test(void)
{
char* str = NULL;
getmemory(&str, 100);
strcpy(str, "hello");
printf(str);//用完没有释放掉
free(str);
str = NULL;
}
int main()
{
test();
return 0;
}

例4.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void test()
{
char* str = (char*)malloc(100);
strcpy(str, "hello");
free(str);//改错题应在free后将str置为空指针,而不是将free放到if语句后面
if (str != NULL)
{
strcpy(str, "hello");
printf(str);
}
}

int main()
{
test();
return 0;
}

同时介绍一下内存中的空间


动态内存开辟3
http://example.com/2021/10/11/动态内存开辟3/
作者
Zevin
发布于
2021年10月11日
许可协议