动态内存开辟相关试题
我们此次会介绍关于动态内存开辟的一些试题,错误点,以及原因
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void getmemory(char* p) { p = (char*)malloc(100); } int main() { char* str = NULL; getmemory(str); strcpy(str, "hello world"); 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 = (char*)malloc(100); return p; } int main() { char* str = NULL; str=getmemory(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
| void getmemory(char** p) { *p = (char*)malloc(100); } int main() { char* str = NULL; getmemory(&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"; return p; } void test(void) { char *str = NULL; str = getmemory(); 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); if (str != NULL) { strcpy(str, "hello"); printf(str); } }
int main() { test(); return 0; }
|
同时介绍一下内存中的空间