C内存泄漏双指针

时间:2018-05-08 18:41:09

标签: c memory-management memory-leaks heap-memory

为什么它不起作用?我有记忆泄漏,但我不知道在哪里。 该程序崩溃并打印随机字符。

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

char** createPyramid(int depth);

int main(int argc, char** argv) {
    printf("\n createPyramid \n");
    int depth = 9;
    char** w = createPyramid(depth);
    for (int i=0;i<depth;i++){
        printf("%s \n",w[i]);
    }
    for (int i = 0;i<depth;i++){
        free(w[i]);
    }
    free(w);
    return 0;
}

char** createPyramid(int depth){
    char** w;
    w = (char**) calloc(depth,sizeof(char));
    for (int i=0;i<depth;i++){
        *(w+i)=(char*) calloc(i+2,sizeof(char));
        for (int j=0;j<i+1;j++){
            (*((*(w+i))+j))='*';
        }
        *((*(w+i))+i+1)='\0';
    }
    return w;
}

2 个答案:

答案 0 :(得分:1)

由于我们可以计算整个金字塔在构建之前将占用多少空间,我们可以通过分配单个缓冲区来简化代码。

第一层需要2 char s(一个用于*,一个用于\n)。然后,下一个图层与前一个图层一样多,加n*个实例和最终\n。因此,总大小是:

f(n) = f(n-1) + n + 1
f(1) = 2

Solving this recurrence equation告诉我们:

f(n) = n * (n+3) / 2

现在我们可以轻松地编写整个金字塔了:

char * createPyramid(int depth)
{
    int i, j;
    int size = depth * (depth + 3) / 2;
    char * buffer = malloc(size + 1);
    char * p = buffer;

    for (i = 0; i < depth; ++i) {
        for (j = 0; j < i + 1; ++j)
            *p++ = '*';
        *p++ = '\n';
    }
    *p = 0;

    return buffer;
}

然后打印出来:

int main()
{
    int depth = 9;
    char * buffer = createPyramid(depth);
    puts(buffer);
    free(buffer);
    return 0;
}

当然,请注意,如果您只想要一个只打印金字塔的程序,您根本不需要动态内存。

答案 1 :(得分:0)

如评论中所述,问题是为char **分配空间。此外,使用索引而不是指针算法更清楚。这有效:

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


char** createPyramid(int depth);                                                                

int main(int argc, char** argv) {                                                               
    printf("\n createPyramid \n");                                                              
    int depth = 9;                                                                              
    char** w = createPyramid(depth);                                                            
    for (int i=0;i<depth;i++){                                                                  
        printf("%s \n",w[i]);                                                                   
    }                                                                                           
    for (int i = 0;i<depth;i++){                                                                
        free(w[i]);                                                                             
    }                                                                                           
    free(w);                                                                                    
    return 0;                                                                                   
}                                                                                               

char** createPyramid(int depth){                                                                
    char** w;                                                                                   
    w = (char**) calloc(depth,sizeof(char*));                                                   
    for (int i=0;i<depth;i++){                                                                  
        w[i] =(char*) calloc(i+2,sizeof(char));                                                 
        for (int j=0;j<i+1;j++){                                                                
            w[i][j] = '*';                                                                      
        }                                                                                       
        w[i][i+1] = '\0';                                                                       
    }                                                                                           
    return w;                                                                                   
}