程序的执行停止 - C(内存分配)

时间:2013-10-08 17:22:42

标签: c memory memory-management

我正在尝试为USACO的Palindromic Squares写一个解决方案 经过大量的检查,虽然我发现了很多错误,但我仍然无法找到为什么我的程序仍然在停止。 我认为这是一种内存管理问题,但我不知道为什么或如何如此。所以,这是代码:

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


char ch(int x){
    if (x < 0 || x > 19) return 0;
    return "0123456789ABCDEFGHIJ"[x];
}

void append( int x, char* num){
    num=realloc(num,sizeof(char)* strlen(num)+2);
    num[strlen(num)+1] = '\0';
    num[strlen(num)] = ch(x);

}

char * baseB(int x, int base){
    int mult=1,lim=1,i;
    char *num;
    num = malloc(sizeof(char));
    num[0] = '\0';
    while(x/(mult*base)){
        mult*=base;
        lim++;
    }
    for(i=0;i<lim;i++){
        append(x/mult,num);
        x %= mult;
        mult/=base;
    }
    return num;
}

int is_pal( char* num ){
    int i;

    for(i=0;i<strlen(num)/2;i++){
        if ( num[i] != num[strlen(num)-1-i] )
            return 0;
    }
    return 1;
}
int main(){

    int x, size=0, y, base;
    int *lst;
    FILE *fp;
    lst=malloc(sizeof(int));
    fp= fopen("palsquare.in","r");
    fscanf(fp,"%d", &base);
    fclose(fp);

    for(x=1;x<301;x++){
        y = x*x;
                    printf(" a0 ");

        printf("%s ", baseB(y,base));
                    printf(" a1 ");

        //printf("%d ", is_pal( baseB(y,base) ) );
                    printf(" a2 ");

        if( is_pal( baseB(y,base) ) ){
            printf(" a3\n");
            size++;
            lst=realloc(lst,sizeof(int)*size);
            lst[size-1]=x;
        }
    }

    fp=fopen("palsquare.out","w");
    for(x=0;x<size;x++){
        fprintf(fp, "%d %d\n", lst[x], lst[x]*lst[x]);
    }
    fclose(fp);
    return 0;


}

创建结果列表的循环在我看来是我问题的原因。关于那里发生了什么的想法,为什么会在那里发生?


编辑:

  1. 更改了开关代码:)
  2. 免费拨打所有对baseB的电话
  3. lst不再是指针
  4. main()的代码现在是:

    int main(){
    
        int x, size=0, y, base;
        int lst[300];
        FILE *fp;
        char *tmp = NULL;
        fp= fopen("palsquare.in","r");
        fscanf(fp,"%d", &base);
        fclose(fp);
    
        for(x=1;x<301;x++){
            y = x*x;
            tmp=baseB(y,base);
            printf("%s ", tmp);
            if( is_pal( tmp ) ){
                size++;
                lst[size-1]=x;
            }
            free(tmp);
            tmp=NULL;
        }
    
        fp=fopen("palsquare.out","w");
        for(x=0;x<size;x++){
            fprintf(fp, "%d %d\n", lst[x], lst[x]*lst[x]);
        }
        fclose(fp);
        return 0;
    
    
    }
    

2 个答案:

答案 0 :(得分:0)

最好的起点可能是释放你分配的所有内存。当然,我不知道这是否真的可以解决任何问题......

问题是baseB返回一个malloc指针,然后将其传递给函数并且从不释放。即时泄漏。

尝试这样的事情:

// At the top of main
char *tmp = NULL;
// All that code until the first baseB
tmp = baseB(y, base);
printf("%s ", tmp); // Or the corresponding is_pal call
free(tmp);
tmp = NULL;

等等。

答案 1 :(得分:0)

num=realloc(num,sizeof(char)* strlen(num)+2);

您修改'num'指针的本地副本。呼叫者功能仍将具有旧的未修改地址。如果地址至少会改变一次 - 你就是骨头。

由于代码已经很乱,最简单的版本(最少修改)将是:

char *append( int x, char* num){
    num=realloc(num,sizeof(char)* strlen(num)+2);
    num[strlen(num)+1] = '\0';
    num[strlen(num)] = ch(x);
    return num;
}

char * baseB(int x, int base){
    int mult=1,lim=1,i;
    char *num;
    num = malloc(sizeof(char));
    num[0] = '\0';
    while(x/(mult*base)){
        mult*=base;
        lim++;
    }
    for(i=0;i<lim;i++){
        num=append(x/mult,num);
        x %= mult;
        mult/=base;
    }
    return num;
}

除此之外,正如评论所示 - 调试一次!调试器优于SO(至少在这种情况下)。