即使在分配内存时也会出现堆溢出

时间:2019-02-21 18:08:45

标签: c

我正在尝试解决leetcode上的n-queen问题。但这给leetcode带来了堆溢出错误。

但是在我的计算机上,当我给出单个输入时,它给出正确的答案,但是在多次输入时,它给出分割错误:11错误。

当我不打印整个棋盘时。只需打印一些不同的可能解决方案。然后它也可以正常工作。

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

#define bool int
#define true 1
#define false 0

//checking positioned queens
bool checkPlacedQueens(char **board, int queeni, int queenj, int n) {
    int i=queeni;
    int j=queenj;

    //checking complete row
    for(int i=queeni; i>=0; i--) {
        if(board[i][j] == 'Q')
            return false;
    }

    i=queeni;
    j=queenj-1;
    //checking left diagonal
    while(i>=0 && j>=0) {
        if(board[i--][j--] == 'Q') 
            return false;
    }

    i=queeni;
    j=queenj+1;
    //checking right diagonal
    while(i>=0 && j<=n) {
        if(board[i--][j++] == 'Q') 
            return false;
    }

    return true;
}

char ***placeQueens(char **board, int queenI, int n, int *returnSize, char ****result) {

    //all queens are on their correct position
    if(queenI == n) {
        (*returnSize)++;

        /*
            reallocating the memory to save all the outputs in 3D 
            array
        */
        (*result) = (char ***) realloc(*result, sizeof(char **)*(*returnSize));
        (*result)[*returnSize-1] = (char **)malloc(sizeof(char *)*n);

        for(int i=0; i<n; i++) {
            (*result)[*returnSize-1][i] = (char *)malloc(sizeof(char)*n);
        }

        for(int i=0; i<n; i++) {
            for(int j=0; j<n; j++) {
                (*result)[*returnSize-1][i][j] = board[i][j];
            }
        }

        return *result;
    }//if

    for(int j=0; j<n; ++j) {
        char save = board[queenI][j];
        board[queenI][j] = 'Q';
        if(checkPlacedQueens(board, queenI-1, j, n)) {
            placeQueens(board, queenI+1, n, returnSize, result);
        }
        board[queenI][j] = save;
    }//for Loop

    return *result;
}//function

char *** solveNQueens(int n, int* returnSize) {
    char **board;
    char ***result = (char ***)malloc(sizeof(char **));

    board = (char **)malloc(sizeof(char *)*n);

    for(int i=0; i<n; i++) {
        board[i] = (char *)malloc(sizeof(char)*n);
    }

    for(int i=0; i<n; i++) {
        for(int j=0; j<n; j++) {
            board[i][j] = '.';
        }
    }

    placeQueens(board, 0, n, returnSize, &result);

    for(int i=0; i<n; i++)
        free(board[i]);
    free(board);

    return result;
}//char

int main(void) {
    int returnSize=0;
    int n=4;
    char ***arr;

    while(n<10) {
        arr = solveNQueens(n, &returnSize);

        for(int i=0; i<returnSize; ++i) {
            for(int j=0; j<n; j++) {
                for(int k=0; k<n; k++) {
                    printf("%c", arr[i][j][k]);
                }
                printf("\n");
            }
            printf("\n");
        }
        printf("\n\n\n");

        for(int i=0; i<returnSize; ++i) {
            for(int j=0; j<n; j++) {
               free(arr[i][j]);
            }
            free(arr[i]);
        }

        free(arr);
        arr=NULL;
        n++;
    }
}//main

2 个答案:

答案 0 :(得分:0)

您的代码具有越界读取非法内存访问权限。现场测试在这里segfault diagnoser

以下是读取的越界的诊断消息。

======扩展DTS消息的开始==(56.133)==从此处开始复制======

[越界读取] 被Stensal DTS检测到。
  继续执行会导致不确定的行为,中止!

+--------------------------------------------------------------------------+
| Reading 1 bytes from 0x80c5054 will read undefined values.
| 
| The object to-be-read (start:0x80c5050, size:4 bytes) is allocated at
|     file:/prog.c::83, 28
| 
|  0x80c5050               0x80c5053
|  +------------------------+
|  | the object  to-be-read |......
|  +------------------------+
|                            ^~~~~~~~~~
|        the read starts at 0x80c5054 that is right after the object end.
| 
| Stack trace (most recent call first) of the read.
| [1]  file:/prog.c::31, 12
| [2]  file:/prog.c::67, 12
| [3]  file:/prog.c::68, 13
| [4]  file:/prog.c::92, 5
| [5]  file:/prog.c::107, 15
| [6]  [libc-start-main]
+--------------------------------------------------------------------------+

========结束DTS消息===============在此处复制结束========

答案 1 :(得分:0)

问题是您每次重新调用returnSize函数时都没有重置solveNQueens的值。

以下是有效代码:

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

#define bool int
#define true 1
#define false 0

//checking positioned queens
bool checkPlacedQueens(char **board, int queeni, int queenj, int n) {
    int i=queeni;
    int j=queenj;

    //checking complete row
    for(int i=queeni; i>=0; i--) {
        if(board[i][j] == 'Q')
            return false;
    }

    i=queeni;
    j=queenj-1;
    //checking left diagonal
    while(i>=0 && j>=0) {
        if(board[i--][j--] == 'Q') 
            return false;
    }

    i=queeni;
    j=queenj+1;
    //checking right diagonal
    while(i>=0 && j<=n) {
        if(board[i--][j++] == 'Q') 
            return false;
    }

    return true;
}

char ***placeQueens(char **board, int queenI, int n, int *returnSize, char ****result) {

    //all queens are on their correct position
    if(queenI == n) {
        (*returnSize)++;

        /*
            reallocating the memory to save all the outputs in 3D 
            array
        */
        (*result) = (char ***) realloc(*result, sizeof(char **)*(*returnSize));
        (*result)[*returnSize-1] = (char **)malloc(sizeof(char *)*n);

        for(int i=0; i<n; i++) {
            (*result)[*returnSize-1][i] = (char *)malloc(sizeof(char)*n);
        }

        for(int i=0; i<n; i++) {
            for(int j=0; j<n; j++) {
                (*result)[*returnSize-1][i][j] = board[i][j];
            }
        }

        return *result;
    }//if

    for(int j=0; j<n; ++j) {
        char save = board[queenI][j];
        board[queenI][j] = 'Q';
        if(checkPlacedQueens(board, queenI-1, j, n)) {
            placeQueens(board, queenI+1, n, returnSize, result);
        }
        board[queenI][j] = save;
    }//for Loop

    return *result;
}//function

char *** solveNQueens(int n, int* returnSize) {
    char **board;
    char ***result = (char ***)malloc(sizeof(char **));

    board = (char **)malloc(sizeof(char *)*n);

    for(int i=0; i<n; i++) {
        board[i] = (char *)malloc(sizeof(char)*n);
    }

    for(int i=0; i<n; i++) {
        for(int j=0; j<n; j++) {
            board[i][j] = '.';
        }
    }

    placeQueens(board, 0, n, returnSize, &result);

    for(int i=0; i<n; i++)
        free(board[i]);
    free(board);

    return result;
}//char

int main(void) {
    int n=4;
    char ***arr;

    while(n<10) {
        // Reset the value of returnSize
        int returnSize=0;

        arr = solveNQueens(n, &returnSize);

        for(int i=0; i<returnSize; ++i) {
            for(int j=0; j<n; j++) {
                for(int k=0; k<n; k++) {
                    printf("%c", arr[i][j][k]);
                }
                printf("\n");
            }
            printf("\n");
        }
        printf("\n\n\n");

        for(int i=0; i<returnSize; ++i) {
            for(int j=0; j<n; j++) {
               free(arr[i][j]);
            }
            free(arr[i]);
        }

        free(arr);
        arr=NULL;
        n++;
    }
}//main