1、动态内存所开辟的空间都是在堆上开辟的;
1、可以向内存申请一块连续可用的空间,并返回这块空间的指针;
2、开辟成功,返回指向空间的指针;
3、开辟失败,返回NULL;
4、malloc申请的空间释放:1、free释放(主动);2、程序退出,操作系统回收(被动释放);
- #include <stdio.h>
- #include <stdlib.h>
- int main()
- {
- // 开辟一块malloc空间
- int* p = (int*)malloc(10 * (sizeof(int)));
- // 判断malloc是否为空
- if (p == NULL)
- {
- // 打印出错误原因
- perror("malloc");
- return 1;
- }
- // 使用malloc开辟的空间
- for (int i = 0; i < 10; i++)
- {
- printf("%d ", *(p + i)); // 未初始化
- }
- return 0;
- }
1、用来释放动态开辟的内存;
2、free的参数的空间不是动态开辟的空间,那free的行为是未定义的;
3、free的参数是NULL指针,函数什么都都不做;
-
- #include <stdio.h>
- #include <stdlib.h>
- int main()
- {
- // 开辟一块malloc空间
- int* p = (int*)malloc(10 * (sizeof(int)));
- // 判断malloc是否为空
- if (p == NULL)
- {
- // 打印出错误原因
- perror("malloc");
- return 1;
- }
- // 使用malloc开辟的空间
- for (int i = 0; i < 10; i++)
- {
- *(p + i) = i;
- printf("%d ", *(p + i));
- }
-
- // free释放空间
- free(p);
- p = NULL; // 最后将指针制为空指针
-
- return 0;
- }
1、calloc也是开辟空间的;
2、calloc会将开辟好的空间全部初始化为0;
- #include <stdio.h>
- #include <stdlib.h>
- int main()
- {
- // 开辟一块calloc空间
- int* q = (int*)calloc(10, sizeof(int));
- if (q == NULL)
- {
- perror("calloc");
- return 1;
- }
- for (int i = 0; i < 10; i++)
- {
- printf("%d ", *(q + i)); // 全都初始化为了0
- }
- free(q);
- q = NULL;
- return 0;
- }
1、realloc函数使用来追加空间的;
2、realloc的返回值不能用追加到指定空间接收;(因为如果追加空间失败,则会导致以前开辟的空间也置为空);
3、如果后续空间被占用,不能直接使用;realloc则会找一块新的空,一次性开辟够;并将就空间中的数据拷贝到新空间中,还会将就得空间释放掉,返回新空间的地址;
4、realloc追加的空间内存放的是随机值;
5、realloc函数的第一个参数如果是一个空指针,那么就等价于malloc函数;
- #include <stdio.h>
- #include <stdlib.h>
- int main()
- {
- // 开辟一块calloc空间
- int* q = (int*)calloc(10, sizeof(int));
- if (q == NULL)
- {
- perror("calloc");
- return 1;
- }
- // 使用realloc追加空间
- // q = (int*)realloc(q, 10 * sizeof(int));
- // 这样写是会出问题的,最好不用自己接收;
- int* q1 = (int*)realloc(q, 10 * (sizeof(int)));
- if (q1 == NULL)
- {
- perror("realloc");
- return 1;
- }
- for (int i = 0; i < 20; i++)
- {
- printf("%d ", *(q + i)); // realloc追加的空间值是随机值
- }
- free(q);
- free(q1);
- q = NULL;
- q1 = NULL;
- return 0;
- }
1、对NULL指针的解引用操作;
2、对动态内存的越界访问;
3、对非动态的内存free释放;
4、使用free释放动态内存的一部分;
5、对同一块动态内存空间多次释放;
6、忘记释放动态内存空间(内存泄漏);
源代码:
- #include
- #include
- #include
- void GetMemory(char* p)
- {
- p = (char*)malloc(100); // 没有内存释放,并且形参不会改变实参;
- }
- void Test(void)
- {
- char* str = NULL;
- GetMemory(str);
- strcpy(str, "hello world"); // 对NULL指针解引用;
- printf(str);
- }
- int main()
- {
- Test();
- return 0;
- }
修改后的代码1:
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- void GetMemory(char** p)
- {
- *p = (char*)malloc(100); // 没有内存释放,并且形参不会改变实参;
- // 这里通过解引用找到首元素地址
- }
- void Test(void)
- {
- char* str = NULL;
- GetMemory(&str); // 所以这里传地址过去,通过形参改变实参;
- strcpy(str, "hello world"); // 对NULL指针解引用;
- printf(str);
- // 使用完后,对动态内存空间进行释放
- free(str);
- str = NULL;
- }
- int main()
- {
- Test();
- return 0;
- }
修改后的代码2:
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- void* GetMemory()
- {
- char* p;
- return p = (char*)malloc(100); // 没有内存释放,并且形参不会改变实参;
- // 将地址传回去
- }
- void Test(void)
- {
- char* str = NULL;
- str = GetMemory();
- strcpy(str, "hello world"); // 对NULL指针解引用;
- printf(str);
- // 最后释放
- free(str);
- str = NULL;
- }
- int main()
- {
- Test();
- return 0;
- }
局部变量出了当前函数就会销毁,千万千万不能返回变量地址,也就是不能返回栈空间地址,那么所接收的指针就成为了野指针;地址是带回来了,但是空间却销毁了;
- char* GetMemory(void)
- {
- char p[] = "hello world";
- return p;
- }
- void Test(void)
- {
- char* str = NULL;
- str = GetMemory(); // str成了野指针了
- printf(str);
- }
这个代码和题目1改造后的代码很像, 只是少了释放动态内存空间,存在内存泄漏;
- #include
- void GetMemory(char** p, int num)
- {
- *p = (char*)malloc(num);
- }
- void Test(void)
- {
- char* str = NULL;
- GetMemory(&str, 100);
- strcpy(str, "hello");
- printf(str);
- }
- int main()
- {
- Test();
- return 0;
- }
- #include
- void Test(void)
- {
- char* str = (char*)malloc(100);
- strcpy(str, "hello");
- free(str);
- if (str != NULL)
- {
- strcpy(str, "world");
- printf(str);
- }
- }
- int main()
- {
- Test();
- return 0;
- }
代码错误注释:
- #include <stdio.h>
- void Test(void)
- {
- char* str = (char*)malloc(100);
- // 未判断NULL
- strcpy(str, "hello");
- free(str);
- // 应该在后面将str置为NULL
- if (str != NULL)
- {
- strcpy(str, "world"); // 先释放了空间,所以这里的str成了野指针
- printf(str);
- }
- }
- int main()
- {
- Test();
- return 0;
- }
还未写完