c语言进阶——二级指针内存模型

二级指针输出模型

//指针做输出:被调用函数分配内存
//指针做输入:主调用函数分配内存
//求文件中的两段话的长度
int getMem(char **myp1, int *mylen1, char **myp2, int *mylen2)
{
    char *tmp1 = NULL;
    char *tmp2 = NULL;
    tmp1 = (char *)malloc(100);
    if (tmp1 == NULL)
    {
        return -1;
    }
    strcpy(tmp1, "abcdefg");
    *mylen1 = strlen(tmp1);

    *myp1 = tmp1; //间接修改实参p1的值

    tmp2 = (char *)malloc(100);
    if (tmp2 == NULL)
    {
        return -2;
    }
    strcpy(tmp2, "11122233333");
    *mylen2 = strlen(tmp2);

    *myp2 = tmp2; //间接修改实参p1的值
    return 0;
}

int getMem_Free(char *myp1)
{
    if (myp1 == NULL)
    {
        return -1;
    }
    free(myp1);  //释放完指针变量 所致的内存空间
    return 0;
}


int main()
{
    char  *p1 = NULL;
    int len1 = 0;

    char *p2 = NULL;
    int len2 = 0;

    int ret = 0;

    ret  = getMem(&p1, &len1, &p2, &len2 );

    printf("p1: %s \n", p1);
    printf("p2: %s \n", p2);

    getMem_Free(p1);
    getMem_Free(p2);  
    p1 = NULL;
    p2 = NULL;

    system("pause");
    return ret;
}

二级指针做输入模型(指针数组)

void printMyArray(char **myArray, int num)
{
    int i = 0;
    for (i=0; i<num; i++)
        printf("%s \n", *(myArray+i) );
}

void sortMyArray(char **myArray, int num)
{
    int i =0 , j = 0;
    char *tmp = NULL;
    //排序
    for (i=0; i<num; i++)
    {
        for (j=i; j<num; j++)
        {
            if (strcmp(myArray[i], myArray[j]) > 0 )
            {
                tmp = myArray[i];  //交换的是指针的值,改变指针的指向
                myArray[i] = myArray[j];
                myArray[j] = tmp;
            }
        }
    }
}

int main()
{
    int     i = 0, j = 0;
    int     num = 0;
    char    *tmp = NULL;
    //数组 数组中的每一个元素是指针 指针数组
    char *myArray[] = {"aaaaaa", "ccccc", "bbbbbb", "111111"};
    //计算元素个数 
    num = sizeof(myArray)/sizeof(myArray[0]);

    printf("排序之前\n");
    printMyArray(myArray, num);

    sortMyArray(myArray, num);


    printf("排序之后\n");
    printMyArray(myArray, num);

    printf("hello...\n");
    system("pause");
    return ;
}

二级指针做输入模型(二维数组)

void printMyArray(char myArray[10][30], int num)
{
    int i = 0;
    for (i=0; i<num; i++)
        printf("%s \n", *(myArray+i) );  
}

void sortMyArray(char myArray[10][30], int num)
{
    int i, j = 0;
    char tmpBuf[30];

    for (i=0; i<num; i++)
    {
        for (j=i+1; j<num; j++)
        {
            if (strcmp (myArray[i],  myArray[j]) > 0)
            {
                strcpy(tmpBuf, myArray[i]);  //交换的是内存块,不是指针的指向 
                strcpy(myArray[i], myArray[j]);
                strcpy(myArray[j], tmpBuf);
            }
        }
    }

}

int main()
{
    int i = 0, j = 0;
    int num = 4;
    char myBuf[30];
    char tmpBuf[30];
    char myArray[10][30] = {"aaaaaa", "ccccc", "bbbbbbb", "1111111111111"};

    //打印 
    printf("排序之前\n");
    printMyArray(myArray, num); 
    sortMyArray(myArray, num);
    //打印 
    printf("排序之后\n");
    printMyArray(myArray, num);

    printf("hello...\n");
    system("pause");
    return 0;
}

与第一种模型的不同之处:
1、交换的是内存块而不是指针的指向。
2、不能用char **myArray作为函数的参数传递二维数组实参。因为第一种模型中,数组存储的是指针,myArray的步长为8个字节(32为4字节),但是在第二个模型中是一个二维数组,编译器只会认为是一个10X30的内存空间,步长为30字节,因此会发生步长错误。

二级指针做输入模型(二级指针)

//为二级指针分配内存 
char **getMem(int num)
{
    int i = 0;
    char **p2 = NULL;
    //为二级指针在堆上分配num个多个以及指针内存(实际上为堆上的指针数组) 
    p2 = (char **)malloc(sizeof(char *) * num); 
    if (p2 == NULL)
    {
        return NULL;
    }
    for (i=0; i<num; i++)
    {
        p2[i] = (char *)malloc(sizeof(char)  * 100  ); //char buf[100];
        sprintf(p2[i], "%d%d%d", i+1, i+1, i+1);
    }
    return p2;
}


void printMyArray(char **myArray, int num)
{
    int i = 0;
    for (i=0; i<num; i++)
    {
        printf("%s \n", *(myArray+i) );
    }
}

void sortMyArray(char **myArray, int num)
{
    int i =0 , j = 0;
    char *tmp = NULL;
    //排序
    for (i=0; i<num; i++)
    {
        for (j=i; j<num; j++)
        {
            if (strcmp(myArray[i], myArray[j]) > 0 )
            {
                tmp = myArray[i];  //交换的是指针的值,改变指针的指向
                myArray[i] = myArray[j];
                myArray[j] = tmp;
            }
        }
    }
}

void getMem_Free(char **p2, int num)
{
    int i = 0;
    //释放内存
    for(i=0; i<num; i++)
    {
        if (p2[i] != NULL)
        {
            free(p2[i]);
            p2[i] = NULL;
        }
    }

    if (p2!=NULL) 
    {
        free(p2);
    }

}


int main()
{
    int i = 0, j = 0;
    char **p2 = NULL;
    int num = 5;
    char *tmp = NULL;
    char tmpbuf[100];
    p2 = getMem(num);

    //排序之前 
    printf("排序之前\n");
    printMyArray(p2, num);

    sortMyArray(p2, num);

    //排序之后 
    printf("排序之后\n");
    printMyArray03(p2, num);
    getMem_Free(p2,  num); //p2是一个野指针
    p2 = NULL//要置为空指针 
    return 0;
}

这种模型实际上为堆上的指针数组,用法与第一种基本一致,区别就是第一种内存分配在栈上而已。

二级指针三种输入模型内存图

    int i = 0;
    //指针数组
    char *   p1[] = {"123", "456", "789"};
    //二维数组
    char p2[3][4]  = {"123", "456", "789"};
    //手工二维内存
    char **p3 = (char **)malloc(3 * sizeof(char *)); //int array[3];
    for (i=0; i<3; i++)
    {
        p3[i] = (char *)malloc(10*sizeof(char)); //char buf[10]

        sprintf(p3[i], "%d%d%d", i, i, i);
    }

这里写图片描述

猜你喜欢

转载自blog.csdn.net/daidaihema/article/details/80623316
今日推荐