找不到Current函数的界限

时间:2014-04-03 13:16:41

标签: c debugging bounds

我正在C上的16384数组上实现插入排序。

排序算法运行正常但遇到free(inser)命令时,调试器输出无法找到当前函数的边界错误。

这是否可能是因为我在64位计算机上使用32位mingw?

int main(void) {
    int i,t,j;
    int *inser = malloc(sizeof(int)*16384);
    int *shell = malloc(sizeof(int)*16384);
    srand(time(NULL));

    for(i=0;i<=16384;i++){
        *(inser+i) = rand()% 17000;;
        *(shell+i) = *(inser+i);
    }


    for(i=1;i<=16384;i++){
        j = i-1;
        while((*(inser+i)<*(inser+j)) && (j >=0)){
            t = *(inser+i);
            *(inser+i) = *(inser+j);
            *(inser+j) = t;
            j--;
            i--;
        }
    }

    for(i=0;i<=16384;i++){
        printf("%d\t",*(inser+i));
    }

    free(inser);
    free(shell);

    return 0;
}

5 个答案:

答案 0 :(得分:1)

除了其他人指出的循环边界错误之外,请查看下面标有“警告”的行(我还清理了代码以使其更具可读性)。在此行中,当j从零开始时,j变为-1。这个值将在这里使用:

while( inser[i] < inser[j] && j >= 0 ) { ... }

逻辑“和”,&&是一个快捷操作符:它的左侧(LHS)始终被评估,右侧只有在LHS评估为“true”时才会被评估。因此,inser[-1]将始终在最后一次内部循环迭代后进行求值,因为j在最终循环测试j--失败之前已经从{0}减少到-1 j>=0,但不是在评估inser[j]之前。

你可以将操作数交换到&&以避免这个问题,得到这个:

while( j>=0 && inser[i] < inser[j] ) { ... }

除此之外,我无法说出您的(更正的)代码是否符合预期。

打开所有编译器警告,您可能会发现一些错误。

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

/* Avoid magic numbers */
#define ARRAY_SIZE   (16384)
#define RAND_CEILING (17000)

int main(void) {
    int i;          /* Indexing and iteration variable. */
    int j;          /* Indexing and iteration variable. */ 
    int t;          /* Temporary variable for swapping. */
    int *inser;     /* Sorted array.                    */
    int *shell;     /* Original array.                  */


    /* Always check the return value of malloc() */
    inser = malloc(ARRAY_SIZE*sizeof(*inser));
    if( inser == NULL ) {
        fprintf(stderr, "Call to malloc() failed for 'inser'.\n");
        exit( EXIT_FAILURE );
    }

    shell = malloc(ARRAY_SIZE*sizeof(*shell));
    if( shell == NULL ) {
        fprintf(stderr, "Call to malloc() failed for 'shell'.\n");
        exit( EXIT_FAILURE );
    }


    /* Seed the PRNG */
    srand(time(NULL));


    /* Correct the bounds on the iteration */
    for(i=0; i<ARRAY_SIZE; i++) {
        inser[i] = shell[i] = rand() % RAND_CEILING;
    }


    /* Sort 'inser' */
    for(i=1; i<ARRAY_SIZE; i++) {
        j = i-1;
        while( inser[i] < inser[j] && j >= 0 ) {
            t = inser[i];
            inser[i] = inser[j];
            inser[j] = t;
            j--;                       /* WARNING: 'j' becomes -1 here */
            i--;
        }
    }


    /* Dump 'inser' to stdout */
    for(i=0; i<ARRAY_SIZE; i++) {
        printf("%d\t", inser[i]);
    }


    /* Cleanup */
    free(inser);
    free(shell);

    return EXIT_SUCCESS;
}

答案 1 :(得分:0)

只需在堆栈上分配缓冲区

int inser[16384];
int shell[16384];

堆是邪恶的儿子。

答案 2 :(得分:0)

更改3个for()循环终止。作为@Joachim Pileborg&amp; @BLUEPIXY指出,for()循环经常执行一次。

for (i = 0; i < 16384; i++) {
... 
for (i = 1; i < 16384; i++) {
...
for (i = 0; i < 16384; i++) {

避免裸体魔术数字

#define ASIZE (16384)
int *inser = malloc(ASIZE * sizeof(int));
...
for (i = 0; i < ASIZE; i++) {

请参阅@Emmet答案,了解-1关注的索引。

答案 3 :(得分:0)

你的第一个for循环将运行16385次,因为它将在(包括)0和16384之间的每个数字运行一次。由于你的数组有16384个元素,你将超越它。这就是Joachim和BLUEPIXY所得到的。 This bytes.com question解释了导致gdb错误的原因。

答案 4 :(得分:0)

确保调试器和编译器可执行文件的路径都指向相同的MingW版本

一点解释:

我遇到了同样的错误。我已经在Windows上安装了MingW软件包。如您所知,某些软件包中的CodeBlocks也随MingW一起提供。因此,我的Windows中有两个MingW。但是,我注意到编译器安装目录(在 Settings / Compiler / Toolchain Executables / 中)的路径设置为不同的路径,而调试器(在 Settings / Debugger / Default 中) ->可执行路径)设置为其他MingW版本。我将它们更改为在CodeBlocks之前显式安装的相同版本。现在,它工作正常。出现erorr / bug的原因可能很多。它对我有用,我希望它也会对其他人有帮助...