栈区,堆区,动态内存开辟,错误及原因

简介: 栈区,堆区,动态内存开辟,错误及原因
#define _CRT_SECURE_NO_WARNINGS 1 
#include<stdio.h>
#include<stdlib.h>
//动态内存开辟的常见错误
//1.对NULL的解引用操作
//int main()
//{
//    int* p = (int*)  malloc(10000000000000000);
//    int i = 0;//没有对NULL==0的判断
//    for (i = 0; i <= 10; i++)
//    {
//         *(p + i)=i;
//    }
//    return 0;
//}
2.对动态开辟空间的越界访问
//int main()
//{
//    int i = 0;
//    int* p = (int*)malloc(10 * sizeof(int));
//    if (p == NULL)
//    {
//        return 1;
//    }
//    for (i = 0; i <= 40; i++)//越界
//    {
//        *(p + i) = i;
//    }
//    free(p);
//    p = NULL;
//    return 0;
//}
//3.使用free()释放非动态开辟的空间(只能是堆区)
//int main()
//{
//    int arr[10]={0};//栈区
//    int* p = arr;
//    free(p);
//    p = NULL;
//    return 0;
//}
//4.使用free()只释放非动态开辟的空间的一部分
//int main()
//{
//    int i = 0;
//    int* p = (int*)malloc(10 * sizeof(int));
//    if (p = NULL);
//    return 1;
//    for (i = 0; i <= 5; i++)
//    {
//        *p++ = i;
//    }
//    free(p);//此时的p已经不是p指向的原来的位置,因为p此时已经无法通过p找到最初的空间,
//    //且如果此时通过p释放空间,此时的p=NULL,则变为释放*(p+4)的空间,错误
//    p = NULL;
//    return 0;
//}
//5.对同一块内存开辟的空间多次释放
//int main()
//{
//    int* p =(int*) malloc(100);
//
//    free(p);
//
//    free(p);//多次释放--会出错,但是如果free(p);p=NULL;free(P);p=NULL,则无事发生
//    p = NULL;
//
//    return 0;
//}
//6.动态内存开辟忘记释放---在程序是24小时运行时,程序不会结束,内存一直泄露,浪费内存空间
//void test()
//{
//    int* p = (int*)malloc(10000);
//    if (p = NULL)
//    {
//        return 1;
//    }
//    //使用----使用之后已经无法返回,空间忘记释放
//}
//int main()
//{
//    test();
//    return 0;
//}
//动态开辟的空间两种回收方式:
// 1.主动使用free()
// 2.程序(不是函数)结束
//在堆上开辟和在栈上开辟的变量不一样,在堆上开辟不销毁,在栈上开辟销毁
//1.在堆上开辟时,地址有意义错误如下,改正如下
#include<string.h>
//void GetMemory(char* p)
//{
//    p = (char*)malloc(100);
//
//}
//void test(void)
//{
//    char* str = NULL;
//    GetMemory(str);
//    strcpy(str, "hello word");
//    printf(str);
//}
//
//int main()
//{
//    test();
//    return 0;
//}
//错误理由:
//str传给GetMemory函数的时候是值传递,所以Getmenory函数的形参p是str的一份临时拷贝,在Getmenory函数内部
//动态申请空间的地址,存放在p中,不会影响外边str,所以当Getmenory函数返回之后,str依然是NULL,所以strcpy
//会失败
//当Getmenory函数返回后,形参p销毁,使得动态开辟的100个字节存在内存泄露,无法释放
//应改为(传址法)
//char* GetMemory(char* p)
//{
//    p = (char*)malloc(100);    //----malloc是在堆上开辟的
//    return p;
//
//}
//void test(void)
//{
//    char* str = NULL;
//    str=GetMemory(str);//传址
//    strcpy(str, "hello word");
//    printf(str);//
//    printf("hello word");//与str打印结果一样,因为传的是h的地址,h的地址所指的字符串
//    free(str);
//    str = NULL;
//
//}
//int main()
//{
//    test();
//    return 0;
//}
//也可改为:(二级指针法)
//void GetMemory(char** p)
//{
//    *p = (char*)malloc(100);//----malloc是在堆上开辟的
//
//}
//void test(void)
//{
//    char* str = NULL;
//    GetMemory(str);
//    strcpy(str, "hello word");
//    printf(str);
//    free(str);
//    str = NULL;
//}
//int main()
//{
//    test();
//    return 0;
//}
//2.在栈上开辟时,(如数组等局部变量)地址没意义
//char* GetMemory(void)
//{
//    char p[]="hello word";    //----malloc是在栈上开辟的,出了函数,p数组空间就还给操作系统,
//    //返回地址是没有实际意义的,如果通过地址访问内存,就是非法内存
//    return p;
//
//}
//void test(void)
//{
//    char* str = NULL;
//    str=GetMemory();
//    printf(str);
//
//}
//int main()
//{
//    test();
//    return 0;
//}
int* f1(void)
{
    int x = 10;//在栈区内创建的局部变量x出了函数就销毁,取地址无意义
    return(&x);
    int* ptr;//局部变量不初始化就是随机值,是野指针
    *ptr = 10;
    return ptr;
}
//全局变量,静态变量,static修饰局部变量,放数据段---静态区----代码段----常量字符串,可执行代码,指针代码
//局部变量,局部数组等放栈上
//malloc,calloc,realloc放在堆上


相关文章
|
1月前
|
编译器 C++
C/C++动态内存开辟(详解)
C/C++动态内存开辟(详解)
|
4月前
|
存储 Java 编译器
【面试知识】Java内存分配之常量池、堆、栈
【面试知识】Java内存分配之常量池、堆、栈
|
6月前
|
存储 编译器 C语言
C语言进阶第六课-----------字符分类函数和内存的开辟 2
C语言进阶第六课-----------字符分类函数和内存的开辟
|
6月前
|
C语言
C语言进阶第六课-----------字符分类函数和内存的开辟 1
C语言进阶第六课-----------字符分类函数和内存的开辟
|
6月前
|
程序员 编译器 C语言
动态内存函数,内存开辟,柔性数组(超详细)
动态内存函数,内存开辟,柔性数组(超详细)
38 0
|
5月前
|
Unix 程序员 Linux
【OSTEP】动态内存开辟 | 内存API常见错误 | UNIX: brk/sbrk 系统调用 | mmap创建匿名映射区域 | mmap创建以文件为基础的映射区域
【OSTEP】动态内存开辟 | 内存API常见错误 | UNIX: brk/sbrk 系统调用 | mmap创建匿名映射区域 | mmap创建以文件为基础的映射区域
178 0
|
28天前
|
编译器 C语言 C++
【C语言】calloc()函数详解(动态内存开辟函数)
【C语言】calloc()函数详解(动态内存开辟函数)
25 0
|
1月前
|
存储 程序员 编译器
【C/C++ 堆栈以及虚拟内存分段 】C/C++内存分布/管理:代码区、数据区、堆区、栈区和常量区的探索
【C/C++ 堆栈以及虚拟内存分段 】C/C++内存分布/管理:代码区、数据区、堆区、栈区和常量区的探索
31 0
|
1月前
|
存储 缓存 Rust
【Rust】——所有权:Stack(栈内存)vs Heap(堆内存)(重点)
【Rust】——所有权:Stack(栈内存)vs Heap(堆内存)(重点)
22 0
|
3月前
|
C++
C++多线程场景中的变量提前释放导致栈内存异常
C++多线程场景中的变量提前释放导致栈内存异常
24 0