【问题标题】:eclipse skips main function instead of executing iteclipse 跳过 main 函数而不是执行它
【发布时间】:2020-06-21 19:40:42
【问题描述】:

我在 WIN10 上使用 eclipse 3.2020,执行我的 main 函数时遇到问题。

当我按原样运行程序时,即使我在第一行添加了 printf 并且退出代码是 -1,073,741,819,我也没有输出到 conole。当我注释掉/删除行 solve(s); 时,代码按预期运行并给出退出代码 0。

编辑:添加完整代码(solve 和 print_sol 都在 solver.c 中)

编辑 2:如 cmets 中所述,问题出在代码(错误)而不是 eclipse 中,我只是假设如果有错误消息将打印。

p.s.:如果 main 函数的另一部分出现运行时错误,我仍然觉得 printf 在开始时不会打印的事实很奇怪。

main.c:

#include "solver.h"
#include <stdlib.h>

int main(int argc, char** argv){
    int **grid = (int**) malloc(sizeof(int*) * 4);
    for (int i = 0; i < 4 ; i++){
        grid[i] = (int*) malloc(sizeof(int) * 4);
    }
    int mat[4][4] = {{1,0,3,0}
                     ,{2,0,0,0}
                     ,{3,0,0,0}
                     ,{4,2,0,0}};
    for (int i = 0; i < 4; i++){
        for (int j = 0; j < 4; j++){
            grid[i][j] = mat[i][j];
        }
    }

    solver *s = create_solver(4, &grid);
    solve(s);
    print_sol(s);
}

求解器.h:


#ifndef SOLVER_H_
#define SOLVER_H_

typedef struct sudoku_solver solver;

/*creates a new solver using the length of one row of the board.
 *Then, the user will follow the instructions on screen to input the board*/
solver* create_solver(int row_len, int ***input_board_ptr);

/*if solver is NULL, an error will appear.
 *Otherwise, The board that was given won't be changed, and neither
 *the solver nor the solution (unless saved before using get_sol)
 *will be accessible after this*/
void destroy_solver(solver *solver);

/*if solver is NULL, an error will appear.
 *Otherwise, it will solve the inputed board*/
void solve(solver *solver);

/*if "solve" wasn't executed before, an error will appear.
 *Otherwise, it will print a solution to the inputed board*/
void print_sol(solver *solver);

/*if "solve" wasn't executed before, an error will appear.
 *Otherwise, returns a solution to the inputed board as a matrix of integers*/
int** get_sol(solver *solver);

#endif /* SOLVER_H_ */

求解器.c:

#include "solver.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>

/*the board will be represented by an array of size NxN.
 *the value of every board cell is between 0 and N when 0
 *means "default value"*/
typedef struct sudoku_solver{
    /*length of one row of the board*/
    int N;
    /*a pointer to the solution board*/
    int ***sol_ptr;
}solver;



solver* create_solver(int row_len, int ***input_board_ptr){
    solver *s = (solver*) malloc(sizeof(solver));
    /*throw an ERROR if the malloc failed*/

    /*row_len is a variable, so we have to declare everything dynamically */
    /*allocating the sol matrix as an array of pointers (1 out of 2D)*/
    int **sol = (int**) malloc(row_len * sizeof(int*));
    for (int i = 0; i < row_len; i++){
        /*allocating every row (the second D)
         *while making sol equal to input_board*/
        sol[i] = (int*) malloc(row_len * sizeof(int));
        for (int j = 0; j < row_len; j++){
            sol[i][j] =  (*input_board_ptr)[i][j];
        }
    }

    s->N = row_len;
    /*if row_len != pow(sqrt(row_len),2) then throw invalid input ERROR*/
    s->sol_ptr = &sol;
    return s;
}

void destroy_solver(solver *s){
    for (int i = 0; i < s->N; i++){
        free((*(s->sol_ptr))[i]);
    }
    free(*(s->sol_ptr));
    free(s->sol_ptr);
    free(s);
}


int* calc_next(int x, int y, int *next, solver *s);

bool isSafe(int x, int y, int val, solver *s);

bool solve_rec(int x, int y, solver *s);

void solve(solver *s){
    int n = s->N;
    int next[2];
    int ***sp = s->sol_ptr;

    //find next empty space
    if ((*sp)[0][0] == 0){
        next[0] = 0;
        next[1] = 1;
    }
    else{
        calc_next(0, 0, next, s);
    }

    int nextX = next[0];
    int nextY = next[1];
    for (int i = 1; i < n; i++){
        if (isSafe(nextX, nextY, i, s)){
            (*sp)[nextX][nextY] = i;
            if(solve_rec(nextX, nextY, s)){
                return;
            }
            //backtrack
            (*sp)[nextX][nextY] = 0;
        }
    }
    printf("no sol");
    return;
}

bool solve_rec(int x, int y, solver *s){
    int n = s->N;
    int next[2];
    int ***sp = s->sol_ptr;

    if (x == n - 1 && y == n - 1){
        return true;
    }

    //find next empty space
    calc_next(x, y, next, s);

    int nextX = next[0];
    int nextY = next[1];
    for (int i = 1; i < n; i++){
        if (isSafe(nextX, nextY, i, s)){
            (*sp)[nextX][nextY] = i;
            if(solve_rec(nextX, nextY, s)){
                return true;
            }
            //backtrack
            (*sp)[nextX][nextY] = 0;
        }
    }
    return false;
}

bool isSafe(int x, int y, int val, solver *s){
    int n = s->N;
    int ***sp = s->sol_ptr;
    /*check row*/
    for (int j = 0; j < n; j++){
        if ((*sp)[x][j] == val){
            return false;
        }
    }

    /*check col*/
    for (int i = 0; i < n; i++){
        if ((*sp)[i][y] == val){
            return false;
        }
    }

    /*check block
     *the index of a block in a grid is just like the index of entry in block.
     *In sudoku, there are bs*bs blocks, and each has bs rows and bs columns*/
    int bs = sqrt(n); // block size
    int block_x_index = x / bs;
    int block_y_index = y / bs;
    for(int i = block_x_index * bs; i < bs * (block_x_index + 1); i++){
        for(int j = block_y_index * bs; j < bs * (block_y_index + 1); j++){
            if ((*sp)[i][j] == val){
                return false;
            }
        }
    }

    return true;
}

/*assuming x,y is not the last place in the grid,
 * finds the next empty place after it*/
int* calc_next(int x, int y, int *next, solver *s){
    int n;
    int ***sp = s->sol_ptr;
    /*find the first empty place*/
    do{
        n = s->N;
        if (y == n - 1){
            x++;
            y = 0;
        }
        else{
            y++;
        }

    }while ((*sp)[x][y] != 0);
    next[0] = x;
    next[1] = y;
    return next;
}

void print_sol(solver *s){
    int n = s->N;
    int bs = sqrt(n); // block size
    char curr;
    int rows_passed, col_passed;
    for (int i = 0; i < n + bs - 1; i++){
        for (int j = 0; j < n + bs - 1; j++){
            //if it's a grid row
            if (i == bs || ((i - bs) % (bs + 1)) == 0){
                //if it's also a grid col
                if (j == bs || ((j - bs) % (bs + 1) == 0)){
                    curr = '+';
                }
                else{
                    curr = '-';
                }
            }
            //if it's only a grid col
            else if (j == bs || ((j - bs) % (bs + 1) == 0)){
                curr = '|';
            }
            else{
                rows_passed = i / (bs + 1);
                col_passed = j / (bs + 1);
                curr = '0' + (*(s->sol_ptr))[i-rows_passed][j-col_passed];
            }
            printf("%c",curr);
        }
        printf("\n");
    }
}

int** get_sol(solver *solver){
    return *(solver->sol_ptr);
}

谢谢。

【问题讨论】:

  • 1. Eclipse 不执行任何操作 - 它只是一个非常复杂的文本编辑器,带有大量插件,可以进行编译、调试和许多其他功能。
  • 如何重现这个问题?solve()函数是做什么的?
  • 控制台报告了编译错误吗?
  • 1) Eclipse 可能不是问题:我们需要首先检查您的代码。 2)“main()不执行”......或“没有打印”?我们知道哪个吗?你只是因为没有看到任何东西而没有执行 ASSUMING main() 吗? 3) print_sol() 做什么??? 建议:尝试使用SSCCE 进行复制
  • FWIW:十六进制的退出状态 1073741819 是 0xc0000005,也就是众所周知的 STATUS_ACCESS_VIOLATION。

标签: c


【解决方案1】:

请了解如何使用您的调试器。在这种情况下,它会将您直接带到问题所在:您在此处因访问冲突(Windows 0xc0000005)而崩溃:

void solve(solver *s) {
    int n = s->N;
    int next[2];
    int ***sp = s->sol_ptr;

    //find next empty space
    if ((*sp)[0][0] == 0) {  // <-- Access violation here: "sp" incorrectly initialized!
        next[0] = 0;
        next[1] = 1;
    }

根本问题是虽然 sudoku_solver.N 被初始化为“4”... sudoku_solver.sol_ptr[0][0] 指向的是未初始化的内存。

PS:

是的,这绝对是“执行”。如果它不运行它就不会崩溃;)

【讨论】:

    猜你喜欢
    • 2012-01-08
    • 2016-04-11
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2016-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多