局部变量,动态内存

#define _CRT_SECURE_NO_WARNINGS//必须放在第一行
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
//#include <vld.h>//必须先安装

/*
* 局部变量:定义在函数内部的变量,包括形参,在栈(stack)中,
     作用域在函数内部有效,生存周期:进入函数创建,退出函数销毁
* void :没有,可以修饰返回值或参数列表
* void *:通用指针,仅仅只标记地址,不包含类型信息
* 动态内存:
*    内存区域:堆(heap),很大接近可用内存,内存申请和销毁需要程序自行管理
*    malloc:
*    calloc:把每个元素初始化为0
*    realloc:
*    free:释放内存,不释放则内存泄漏
*    泄漏的内存什么情况还给系统:
*        1.程序(进程)退出
*        2.关机(重启)
*    应用场景:
        1.需要根据变量作为长度定义数组
        2.函数结束后还需要继续使用的内存(例如返回局部数组的地址,链表)
        3.长度较大的数组(大内存,超过栈1M的大小)

*/

char* GetStr1()//error
{
    char str[] = "hello world";
    return str;//0x00200
}

int Getnum()
{
    int a = 10;
    return a;
}

char* GetStr()
{
    int len = strlen("hello world");
    //char* str = (char*)malloc(len * sizeof(char));//常见错误
    char* str = (char*)malloc((len+1) * sizeof(char));
    assert(str != NULL);
    strcpy(str,"hello world");

    return str;
}

//课堂练习,返回str复制n次,("abc",2)->"abcabc"
char* GetMemory(const char* str, int n)
{
    char *p = (char *)malloc(strlen(str)*n +1);
    assert(p != NULL);
    if (p == NULL)
    {
        perror("");
        return NULL;
    }

    p[0] = '\0';//把p变成字符串
    for (int i = 0; i < n; i++)
        strcat(p,str);

    return p;
}

//int main()
//{
//    int n = 10;
//    int *arr = (int *)calloc(n,sizeof(int));
//    for (int i = 0; i < n; i++)
//        printf("%d ",arr[i]);
//    free(arr);
//
//    return 0;
//}

int main()//作业
{
    int n = 10;
    int* arr = (int*)malloc(n * sizeof(int));
    assert(arr != NULL);
    for (int i = 0; i < n; i++)//模拟arr被使用
        arr[i] = i;
    //使用的过程中发现内存不足,实际需要20个单元
    //1.申请更大的内存
    //2.把原数据复制到新内存
    //3.释放原内存
    //4.更新地址

    return 0;
}

//int main()
//{
//    int* arr = (int*)malloc(40);
//    free(arr);
//    return 0;
//}

//int main()
//{
//    //定义1000000长度的int数组
//    //int arr[1000000];//不能定义这么大的数组
//    //int* arr = (int*)malloc(1000000 * sizeof(int));//ok
//    //char* arr = (char*)malloc(1024 * 1024 * 1024);//1G,ok
//    char* arr = (char*)malloc(1024 * 1024 * 1020*2);//20亿字节,2G失败
//    if (arr == NULL)
//        perror("出错了");
//    assert(arr != NULL);
//    printf("好了\n");
//    getchar();
//    free(arr);
//
//    return 0;
//}

//int main()
//{
//    char* p = GetMemory("abcde",5);
//    printf("%s\n",p);
// free(p);
//    return 0;
//}

//int main() 
//{
//    char* p = GetStr();//0x00200
//    printf("%s\n",p);
//
//    int n = Getnum();
//    printf("%d\n",n);
//
//    return 0;
//}

//int main(void)
//{
//    int n = 10;
//    //int arr[n];//error,变量不能作为数组的长度,C99合法
//    int *p = (int *)malloc(n*sizeof(int));//创建成功后,p类似数组名
//    assert(p != NULL);
//    if (p == NULL)
//    {
//        perror("出错了");
//        return 0;
//    }
//
//    for (int i = 0; i < n; i++)
//        p[i] = i;
//    for (int i = 0; i < n; i++)
//        printf("%d ",p[i]);
//
//    return 0;
//}

//课堂练习
//int main()
//{
//    int n;
//    scanf("%d",&n);
//    //创建n长度的double类型数组
//    double* arr = (double*)malloc(n * sizeof(double));
//    assert(arr != NULL);
//    if (arr == NULL)
//        return -1;
//    for (int i = 0; i < n; i++)
//        arr[i] = i;
//    for (int i = 0; i < n; i++)
//        printf("%.1f ",arr[i]);
//
//    return 0;
//}

#define _CRT_SECURE_NO_WARNINGS//必须放在第一行
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <vld.h>
/*
*动态内存: 一定把它当作数组使用
*    内存区域:堆(heap),很大接近可用内存,内存申请和销毁需要程序自行管理
*    malloc:动态申请内存
*    calloc:把每个元素初始化为0
*    realloc:扩容,数据结构(顺序表,顺序栈,C++中string)
*    free:释放内存,不释放则内存泄漏
*    free崩溃的原因:
*      1.越界
*      2.移到指针
*      3.重复释放或者释放非动态内存
*     
*/
/*
* 1.二进制求和
给你两个二进制字符串 `a` 和 `b` ,以二进制字符串的形式返回它们的和。
​    例1:输入参数("11","1"),返回"100";例2:输入("1010","1011"),返回"10101"
*/
char* AddBinary(char* str1, char* str2)
{
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    int n = len1 > len2 ? len1 : len2;
    char* s = (char*)malloc((n + 1 + 1) * sizeof(char));
    assert(s != NULL);
    char* p1 = str1 + len1-1;//str1的尾
    char* p2 = str2 + len2 - 1;//str2的尾
    int i = 0;//s的下标
    int tmp = 0;//保存进位
    int count;//和
    while (p1 >= str1 && p2 >= str2)//p1,p2都还有值
    {
        count = (*p1 - '0') + (*p2 - '0') + tmp;
        s[i++] = count%2 + '0';
        tmp = count / 2;
        p1--;
        p2--;
    }
    while (p1 >= str1)//只剩p1
    {
        count = (*p1 - '0') + tmp;
        s[i++] = count % 2 + '0';
        tmp = count / 2;
        p1--;
    }
    while (p2 >= str2)//只剩p2
    {
        count = (*p2 - '0') + tmp;
        s[i++] = count % 2 + '0';
        tmp = count / 2;
        p2--;
    }
    if (tmp > 0)
        s[i++] = '1';
    s[i] = '\0';

    //s逆置
    --i;//跳过'\0'
    for (int j = 0; j < i; j++, i--)
    {
        tmp = s[i];
        s[i] = s[j];
        s[j] = tmp;
    }
    return s;
}

/*
* 4.有 n 个整数,使前面各数顺序向后移 m 个位置,
最后 m 个数变成最前面的 m个数,见下图,
写一个函数实现该功能。 
*/
void Move(int* arr, int n, int m)
{
    if (m < 0 || m >= n)
        return;
    int* brr = (int*)malloc(m * sizeof(int));
    assert(brr != NULL);
    //把后面m个数据移到brr
    
    //把arr的前n-m个数据后移m个位置
    //把brr的数据复制到arr的前面
    free(brr);
}
int main()
{
    char str1[] = "0101";
    char str2[] = "101";
    char *p = AddBinary(str1,str2);
    printf("%s\n",p);
    free(p);

    return 0;
}

/*
//1.越界
int main()
{
    int n = 10;
    int* arr = (int*)malloc(n );
    assert(arr != NULL);
    for (int i = 0; i < n; i++)
        arr[i] = i;
    for (int i = 0; i < n; i++)
        printf("%d ",arr[i]);
    printf("\n");
    free(arr);

    return 0;
}
*/

/*
//2.移到指针
int main()
{
    int n = 10;
    int* arr = (int*)malloc(n*sizeof(int));
    assert(arr != NULL);
    for (int i = 0; i < n; i++)    
    {//arr[i] = i;
        *arr = i;
        arr++;
    }

    printf("\n");
    free(arr);

    return 0;
}
*/
/*
//重复释放同一段内存
int main()
{
    int n = 10;
    int* arr = (int*)malloc(n * sizeof(int));
    assert(arr != NULL);
    for (int i = 0; i < n; i++)
    {
        arr[i] = i;
    }
    
    printf("%p\n", arr);
    free(arr);
    printf("%p\n",arr);//arr是野指针
    free(NULL);//可以
    //free(arr);//崩溃,重复释放

    return 0;
}
*/
//int main()
//{
//    int n = 10;
//    int* arr = (int*)malloc(n * sizeof(int));
//    assert(arr != NULL);
//    free(arr);
//
//    arr = (int*)malloc(2*n * sizeof(int));//arr还能不能继续使用
//
//    free(arr);
//
//    return 0;
//}
//int main()
//{
//    int n = 10;
//    int* arr = (int*)malloc(n * sizeof(int));
//    assert(arr != NULL);
//    printf("%p\n",arr);
//    arr = (int*)realloc(arr,n*2*sizeof(int));
//    printf("%p\n", arr);
//    free(arr);
//    return 0;
//}

/*
int main()
{
    int n = 10;
    int* arr = (int*)malloc(n * sizeof(int));
    assert(arr != NULL);
    for (int i = 0; i < n; i++)//模拟arr被使用
        arr[i] = i;
    //使用的过程中发现内存不足,实际需要20个单元
    arr = (int *)realloc(arr,2*n*sizeof(int));//等同下面所有语句
    1.申请更大的内存
    //int* p = (int*)malloc(2 * n * sizeof(int));
    //assert(p != NULL);
    2.把原数据复制到新内存
    //for (int i = 0; i < n; i++)
    //{
    //    p[i] = arr[i];
    //}
    3.释放原内存
    //free(arr);
    4.更新地址
    //arr = p; p = NULL;

    return 0;
}
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值