首页 > 解决方案 > 分段错误(Malloc/Free in a Loop)

问题描述

我一直在重新审视 C 语言,并且在我的程序中使用后无法释放内存:

    int tvalue = 2;
    while (smult == 0) {
        int * tvaluearray = calloc(allnum, sizeof(int));    
        tvaluearray = frequencyArray(tvalue, allnum, tvaluearray);
        printf("tvalue = %d\n", tvalue);    
        //compare each index of the tvaluearray and the first array
        for (int j = 0; j < allnum; j++) {
//          printf("tvaluearray[%d]=%d >= firstarray[%d]=%d\n", j, tvaluearray[j], j, firstarray[j]);
            if (tvaluearray[j] < firstarray[j]) {
            //  printf("Found the false statement\n");
                break;
            }
            else if ( (j+1) == allnum ){
                smult = 1;
//              printf("Made it to else if! smult = %d\n", smult);
            }
        }
        free(tvaluearray);
        ++tvalue;
    }

frequencyArray 函数如下所示:

int * frequencyArray (int target, int allnum, int targetarray[]) {
    int divisor = 2;

    for (int i = 0; i < allnum; i++)
        targetarray[i] = 0;
    //find the common factor frequency of the given number
    while (target > 1) {
        if (target % divisor == 0) {
            targetarray[divisor] += 1;
            target /= divisor;
        }
        else
            ++divisor;
    }


    return targetarray;
}

在玩过这个之后,我尝试了以下不同的结果:

1)删除免费的targetarray:

tvalue = 1306 --> 段错误

2)包括免费(targetarray):

tvalue = 29 free():下一个大小无效(快速)中止(核心转储)

3) 包括 free(targetarray) 并为 tvaluearray calloc 分配 4*sizeof(int) 而不是 int:

tvalue = 31468 --> 段错误

第三个测试让我在我的程序遇到分段错误错误之前以不同的结果更改数组的分配空间。这让我觉得我分配空间的方式存在问题,但我认为这可能有点超出我目前的理解。你们中的任何人都看到我可能会出错的地方吗?

标签: cmallocfree

解决方案


frequencyArray()函数中,您有一个循环:

while (target > 1) {
    if (target % divisor == 0) {
        targetarray[divisor] += 1;
        target /= divisor;
    }
    else
        ++divisor;
}

wheredivisor用作您的targetarray[]. 我在这里看不到最大值的任何正式界限divisor- 它似乎可以超过最大允许值(等于),因此可以覆盖allnum - 1外部内存,从而导致内存损坏/分段错误。targetarray[]您应该在每次迭代中检查divisor < allnum.

不幸的是,我不知道你的代码的上下文,所以不能在这里提出任何适当的解决方案。可能它应该看起来像:

while (target > 1) {
    if (target % divisor == 0) {

        // 'fuse' ;)
        if (divisor >= allnum) {
           // place here the code needed to solve the problem or break to exit from loop
        }
        // end of 'fuse'

        targetarray[divisor] += 1;
        target /= divisor;
    }
    else
        ++divisor;
}

推荐阅读