malloc

什么是堆内存

//一定要掌握

// - 堆内存基本特征:

// - 相比栈内存,堆的总大小仅受限于物理内存,在物理内存允许的范围内,系统对堆内存的申请不做限制。

// - 相比栈内存,堆内存从下往上增长。

// - 堆内存是匿名的,只能由指针来访问。

// - 自定义分配的堆内存,除非开发者主动释放,否则永不释放,直到程序退出。

#include<stdio.h>

#include<stdlib.h>

int main(int argc, char const *argv[])

{char *p="jack";char *str=malloc(100);

​    str=p;// str[0]='k';printf("%s",p);return 0;

}

malloc基本定义与用法

malloc函数是一种分配长度为num_bytes字节的内存块的函数,可以向系统申请分配指定size个字节的内存空间。malloc的全称是memory allocation(动态内存分配),当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存。返回类型是 void* 类型。void* 表示未确定类型的指针。C,C++规定,void* 类型可以通过类型转换强制转换为任何其它类型的指针。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(int argc, char const *argv[])
{   //  申请堆空间,可以存放100个char类型
    char *str=malloc(sizeof(char)*100);
    //str="jack";//str指向字符串常量,写法异常
    memcpy(str,"jack",5);
    str[2]='g';
    printf("%s\n",str);




    //申请整型堆空间
    int a[10]={1,2,3,4,5};
    int *int_p=malloc(sizeof(int)*10);
    //手动清空malloc
    memset(int_p,0,sizeof(int)*10);
    int_p[0]=10;//*int_p
    int_p[1]=20;//*(int_p+1)
    int_p[2]=30;
    printf("%d\n",int_p[2]);

    memcpy(int_p,a,sizeof(a)/sizeof(a[0]));
    printf("%d\n",int_p[1]);
    printf("%d\n",int_p[2]);

    //释放堆空间
    free(int_p);
    //释放堆空间后,无法通过in_p访问堆空间
    memcpy(int_p,a,sizeof(a)/sizeof(a[0]));//无法访问
    printf("%d\n",int_p[1]);

    
    return 0;
}

练习:练习用堆空间完成冒泡排序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(int argc, char const *argv[])
{
    printf("inputdata:");
    int a[5]={0};
    for(int i=0;i<5;i++)
    {
        scanf("%d",&a[i]);
    }
    
    int len=sizeof(a)/sizeof(a[0]);
    int *p=malloc(sizeof(int)*5);
    memset(p,0,sizeof(int)*5);
    memcpy(p,a,sizeof(a));

    for(int i=0;i<len-1;i++)
    {
        for(int j=0;j<len-1-i;j++)
        {
            if(p[j]>p[j+1])
            {
                int temp=0;
                temp=p[j];
                p[j]=p[j+1];
                p[j+1]=temp;
            }
        }
        
    }

    for(int i=0;i<len;i++)
    {
        printf("%d",p[i]);
    }
    free(p);
    return 0;
}

用malloc开辟二维数组

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(int argc, char const *argv[])
{   //      malloc是以字节为单位
    // int *ptr=malloc(sizeof(int)*3);
    // //数组[]表示数据的个数,总大小是数据个数乘以类型

    // for(int i=0;i<3;i++)
    // {
    //     ptr[i]=i;
    // }

    //将malloc转为二维数组

    int **ptr1=(int**)malloc(sizeof(int)*3);//代表三行
    int count=0;
    for(int i=0;i<3;i++)
    {
        
        for(int j=0;j<4;j++)
        {

            ptr1[i]=(int*)malloc(4*sizeof(int));
            ptr1[i][j]=++count;
            printf("%d\t",ptr1[i][j]);

        }
        printf("\n");
    }

    return 0;
}

求子集

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int **subsets(int *nums, int numSize, int *returnSize, int **returnColnumSize)
{
    // 子集个数
    int row = 1 << numSize;
    // 子序列
    int childNums[numSize * sizeof(int)];
    *returnSize = row;
    *returnColnumSize = calloc(row,sizeof(int));
    
    int col = 0;
   
    memset(childNums,0,numSize * sizeof(int));

    // 申请堆空间,存放每个子集的首元素地址
    int **allStr = (int **)calloc(row,sizeof(int *));
    if(allStr == NULL)
    {
        perror("calloc failed: ");
        return NULL;
    }

    for(int i = 0; i < row; i++)
    {
        col = 0;
        for(int j = 0; j < numSize; j++)
        {
            // 对i的每一位尝试构成子集
            if(i & (1 << j))
            {
                // 如果i的第j位的二进制位为真,则nums[j]元素入子集
                childNums[col++] = nums[j];
            }
        }
        // 申请空间用于存放子集
        int *temp = (int *)calloc(col,sizeof(int));
        memcpy(temp, childNums, col*sizeof(int));
        // 将temp挂在allStr的某一个元素
        allStr[i] = temp;
        // 记录每个子集的元素个数
        returnColnumSize[0][i] = col;
    }
    return allStr;
}

int main(int argc, char const *argv[])
{
    int nums[] = {1,2,3};
    // nums元素的个数
    int size = sizeof(nums) / sizeof(nums[0]);
    int returnSize;
    int *returnColnumSize;
    int **allStr = subsets(nums, size, &returnSize, &returnColnumSize);

    // 遍历集合
    for(int i = 0; i < returnSize; i++) // 遍历allStr
    {
        for(int j = 0; j < returnColnumSize[i]; j++)
        {
            printf("%d\t",allStr[i][j]);
        }
        printf("\n");
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值