二级指针指向内存释放问题

/*要求:将二级指针第一种内存模型和第二种内存模型拷贝到第三种内存模型
int copyptr(char (*myp1)[10],int num1,char **myp2,int num2,char **myp3,int num3);/
问题:释放malloc内存时程序当掉,原因不明
程序当掉的地方在freep01()函数那里,已标记开始当掉之处


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

int sort(char **myp3, int num3)
{
    char **p = myp3;
    char *tmp = NULL;
    int i = 0, j = 0;
    if (myp3 == NULL)
    {
        printf("sort() 函数参数传递出错\n");
        return 1;
    }
    for (i=0; i < num3; i++)
    {
        for (j=i+1; j < num3; j++)//错误,需把内容复制而不是指针交换
        {
            if (strcmp(p[i], p[j]) > 0)
            {
                tmp = p[i];
                p[i] = p[j];
                p[j] = tmp;
            }
        }
    }
    return 0;
}
int copyptr(char (*myp1)[30], int num1, char **myp2, int num2, char ***myp3, int *num3)
{
    int i = 0, j = 0, k = 0;
    char **p3 = NULL;
    p3 = (char **)malloc(sizeof(char *) * (num1 + num2));
    if (p3 == NULL)
    {
        printf("copyptr() 分配p3二级指针内存失败\n");
        return 1;//注意此时还没释放内存
    }
    if (myp1 == NULL || myp2 == NULL || myp3 == NULL || num3 == NULL)
    {
        printf("参数传递出错\n");
        return 2;
    }
    char(*p1)[30] = myp1;
    char **p2 = myp2;
    *num3 = num1 + num2;
    for ( i = 0; i < num1; i++)//拷贝第一种内存
    {
        k = strlen(p1[i])+1;
        p3[i] = (char *)malloc(sizeof(char)*k);
        strcpy(p3[i], p1[i]);
        p3[i][k] = '\0';
    }
    for (j = 0; j < num2; j++,i++)//拷贝第二种内存
    {
        k = strlen(p2[j]) + 1;
        p3[i] = (char *)malloc(sizeof(char)*k);
        strcpy(p3[i], p2[j]);
        p3[i][k] = '\0';
    }
    int ret = sort(p3, *num3);
    if (ret != 0)
    {
        printf("sort() err\n");
        return 3;
    }
    *myp3 = p3;
    return 0;
}

int freep01(char **myp, int num)
{
    char **p = myp;
    if (myp == NULL)
    {
        return 1;
    }
    for (int i = 0; i < num; i++)
    {
        free(p[i]);//运行到这里程序当掉
        p[i] = NULL;
    }
    free(p);
    p = NULL;
    return 0;
}
int freep02(char ***myp, int num)
{
    char **p = *myp;
    if (myp == NULL)
    {
        return 1;
    }
    for (int i = 0; i < num; i++)
    {
        free(p[i]);
        p[i] = NULL;
    }
    free(p);
    p = NULL;
    return 0;
}
void main()
{
    char p1[][30] = { "aaaaaa","bbbbb","ccccccc" };
    char *p2[] = { "1111","222222","33333333"};
    char **p3 = NULL;
    int len1 = sizeof(p1) / sizeof(p1[0]);
    int len2 = sizeof(p2) / sizeof(p2[1]);
    int len3 = 0;
    int ret = copyptr(p1, len1, p2, len2, &p3, &len3);
    if (ret != 0)
    {
        printf("copyptr() err\n");
        return;
    }
    for (int i = 0; i < len3; i++)
    {
        printf("%s\n", p3[i]);
    }
    printf("总共%d个字符串\n", len3);

    ret = freep01(p3, len3);
    if (ret != 0)
    {
        printf("freep01() err\n");
        return;
    }

}

图片说明

int copyptr(char (*myp1)[30], int num1, char **myp2, int num2, char ***myp3, int num3)
{
int i = 0, j = 0, k = 0;
char **p3 = NULL;
p3 = (char *
)malloc(sizeof(char *) * (num1 + num2));
if (p3 == NULL)
{
printf("copyptr() 分配p3二级指针内存失败\n");
return 1;//注意此时还没释放内存
}
if (myp1 == NULL || myp2 == NULL || myp3 == NULL || num3 == NULL)
{
printf("参数传递出错\n");
return 2;
}
char(*p1)[30] = myp1;
char **p2 = myp2;
*num3 = num1 + num2;
for ( i = 0; i < num1; i++)//拷贝第一种内存
{
k = strlen(p1[i])+1;
p3[i] = (char *)malloc(sizeof(char)*k);
strcpy(p3[i], p1[i]);
p3[i][k-1] = '\0';//【注释】//将k改为k-1,长度为k,最后一个元素为k-1,前面释放未申请内存,故报错;
}
for (j = 0; j < num2; j++,i++)//拷贝第二种内存
{
k = strlen(p2[j]) + 1;
p3[i] = (char *)malloc(sizeof(char)*k);
strcpy(p3[i], p2[j]);
p3[i][k-1] = '\0';//【注释】//将k改为k-1,长度为k,最后一个元素为k-1,前面释放未申请内存,故报错;
}
int ret = sort(p3, *num3);
if (ret != 0)
{
printf("sort() err\n");
return 3;
}
*myp3 = p3;
return 0;
}

http://bbs.csdn.net/topics/390790094

你的问题是,你的问题是
int ret = copyptr(p1, len1, p2, len2, &p3, &len3);
这里带不出二级指针p3,函数里分配了p3,修改指针的值,但是调用后主程序的p3还是NULL,如果你希望带出,得使用三级指针