尝试在 C 中读取迷宫文本文件时出现 malloc 错误

muro0814

我试图让我的代码从内容涉及的文本文件中读取:(文本文件称为 maze1.txt)

5 5
%%%%%
S % %
% % %
%   E
%%%%%

但是,每当我尝试运行该程序时,我都会收到一个分段错误,我认为这与我使用 malloc 的方式有关。我知道我使用了第一个数字来为我的数组设置边界,但我不确定如何做到这一点。

提供的是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include "maze.h"
maze_t * createMaze(char * fileName)
{
    typedef struct Maze{
    int cols, rows;
    char **charRow;
    }MAZE;
    struct Maze maze;
    FILE *pf;
    int i,j,k;
    pf = fopen(fileName,"r");
    k = fscanf(pf, "%i %*c %i", &maze.cols, &maze.rows);
    char cMaze[maze.cols][maze.rows];
    int new;
    int *newMaze = (int *)malloc( maze.rows * maze.cols * sizeof(int));
    for(i = 0; maze.rows; i++){
        for(j = 0; j < maze.cols; j++){
            cMaze[i][j] = fgetc(pf);
            putchar( cMaze[i][j] ); 

        }       
    }
    printf("%d", cMaze[maze.cols][maze.rows]);
    printf("\n");
    maze.charRow = newMaze;
    fclose(pf);


    return newMaze;
}

这是我的主要内容:

#include <stdio.h>
#include "maze.h"


int main(int argc, char **argv)
{
    if (argc < 2)
    {
        printf("You need a valid input maze file.\n");
        return -1;
    }

    printf("Creating maze with file %s\n", argv[1]);
    maze_t * maze = createMaze(argv[1]);

    printf("\nUnsolved maze:\n");
    printMaze(maze);

    if(solveMazeManhattanDFS(maze, maze->startColumn, maze->startRow))
    {
        printf("\nSolved maze:\n");
        printMaze(maze);
        if(checkMaze(maze))
        {
            printf("Solution to maze is valid\n");
        }
        else
        {
            printf("Incorrect solution to maze\n");
        }
    }
    else
    {
        printf("\nMaze is unsolvable\n");
    }

    printf("\nDestroying maze\n");

    destroyMaze(maze);

    return 0;
}

struct maze_t 的定义是

typedef struct {
    int width;
    int height;
    int startColumn;
    int startRow;
    int endColumn;
    int endRow;
    char ** cells;
} maze_t;
大卫·C·兰金

您无法知道是createMaze成功还是失败,因为您无法验证您的文件实际上是否已打开以供阅读。当您保存 的返回时fscanf,您无法以任何方式验证实际发生了 2 次转换。

使用fscanf是第一行罚款,但明白,'\n'留在stdin你必须你的下一个读之前考虑这一点。(您的下一次阅读是fgetc- 它会很乐意'\n'将文件中的下一个值作为下一个值并将其分配给cMaze[0][0].

二维数组等同于char **如果您计划存储构成迷宫的行并通过 引用它们char **charRow;,那么您需要maze.rows为 char分配指针数量,然后您需要为每一行分配存储空间并将该存储块的起始地址分配给每个maze.charRow[x]. (对于面向行的输入,fgets是读取每一行的更好选择)

您为 分配newMaze,但不分配任何值。

与其为您修复现有代码,让我提供一个示例来正确验证您需要采取的每一步,将每一行存储在maze.line[x](您重命名的charRow)中,使用存储的值输出迷宫,然后释放所有分配的内存(每行 +指针)在退出之前。每个单独的验证都在下面的评论中进行了描述,例如

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

#ifndef BUF_SIZ
#define BUF_SIZ 8192
#endif

typedef struct {
    int cols, rows;
    char **line;
} maze_t;

void *xcalloc (size_t nmemb, size_t sz);

int main (int argc, char **argv) {

    char buf[BUF_SIZ] = "";
    int n = 0;
    maze_t maze;
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    /* read maze.rows & maze.cols */
    if (fscanf (fp, "%d %d", &maze.rows, &maze.cols) != 2) {
        fprintf (stderr, "error: failed to read rows & cols.\n");
        return 1;
    }
    fgets (buf, BUF_SIZ, fp);   /* read discard any additional chars */

    /* allocate/validate maze.rows pointers */
    maze.line = xcalloc (maze.rows, sizeof *maze.line);

    /* read each remaining line up to maze.rows lines */
    while (n < maze.rows && fgets (buf, BUF_SIZ, fp)) {
        size_t len = strlen (buf);      /* get buf length */
        if (len && buf[len-1] == '\n')  /* validate last char is '\n' */
            buf[--len] = 0;             /* overwrite with nul-character */
        else {      /* line too long, handle error */
            fprintf (stderr, "error: line exceeds BUF_SIZ.\n");
            return 1;
        }
        if (len != (size_t)maze.cols) { /* validate maze.cols chars read */
            fprintf (stderr, "error: line exceeds maze.cols.\n");
            return 1;
        }

        /* allocate/validate maze.cols +1 chars */
        maze.line[n] = xcalloc (len + 1, sizeof *maze.line[n]);
        strcpy (maze.line[n++], buf);   /* copy buf to maze.line[n] */
    }

    if (fp != stdin) fclose (fp);   /* close file if not stdin */

    if (n != maze.rows) {   /* validate maze.rows lines read */
        fprintf (stderr, "error: less than maze.rows lines read.\n");
        return 1;
    }

    for (int i = 0; i < n; i++) {
        printf ("%s\n", maze.line[i]);  /* output each line */
        free (maze.line[i]);            /* free line */
    }
    free (maze.line);                   /* free pointers */

    return 0;
}

/** xcalloc allocates memory using calloc and validates the return.
 *  xcalloc allocates memory and reports an error if the value is
 *  null, returning a memory address only if the value is nonzero
 *  freeing the caller of validating within the body of code.
 */
void *xcalloc (size_t nmemb, size_t sz)
{
    register void *memptr = calloc (nmemb, sz);
    if (memptr == 0) {
        perror ("xcalloc() error: virtual memory exhausted.");
        exit (EXIT_FAILURE);
    }

    return memptr;
}

希望这将为您需要在代码中更正的每个步骤提供一个工作示例。注意:xcalloc函数只是为了方便起见,以免重复代码体中的验证)

示例使用/输出

$ ./bin/maze <dat/maze.txt
%%%%%
S % %
% % %
%   E
%%%%%

内存使用/错误检查

在你写的,可动态分配内存的任何代码,你有2个职责关于分配的内存中的任何模块:(1)始终保持一个指针起始地址的内存,因此块,(2),可以释放时,它是没有不再需要。

对于Linuxvalgrind是正常的选择。每个平台都有类似的内存检查器。它们都易于使用,只需通过它运行您的程序即可。

$ valgrind ./bin/maze <dat/maze.txt
==18822== Memcheck, a memory error detector
==18822== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==18822== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==18822== Command: ./bin/maze
==18822==
%%%%%
S % %
% % %
%   E
%%%%%
==18822==
==18822== HEAP SUMMARY:
==18822==     in use at exit: 0 bytes in 0 blocks
==18822==   total heap usage: 6 allocs, 6 frees, 70 bytes allocated
==18822==
==18822== All heap blocks were freed -- no leaks are possible
==18822==
==18822== For counts of detected and suppressed errors, rerun with: -v
==18822== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

始终确认您已释放所有分配的内存并且没有内存错误。

仔细查看,努力将验证合并到您的代码中,如果您有任何其他问题,请告诉我。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

尝试释放malloc时出现错误

来自分类Dev

从 C 中的文本文件读取时出现意外错误

来自分类Dev

尝试:为什么出现malloc错误

来自分类Dev

C ++中的Malloc错误?

来自分类Dev

有没有办法读取文本文件并将其保存在 C 中的动态字符数组中,然后尝试并获得 'malloc(): memory Corruption'

来自分类Dev

尝试从C中的文本文件读取信息

来自分类Dev

尝试从邮筒读取时出现C读取文件错误87

来自分类Dev

尝试从邮筒读取时出现C读取文件错误87

来自分类Dev

读取文本文件错误C

来自分类Dev

读取文本文件时C程序中的分段错误

来自分类Dev

从 c 中的文本文件读取浮点数时的错误值

来自分类Dev

Java在尝试读取文本文件时遇到运行时错误

来自分类Dev

尝试创建文本文件时出现参数Null异常错误

来自分类Dev

C ++中向量上的Malloc错误

来自分类Dev

malloc导致C中的分段错误

来自分类Dev

使用malloc的C中的分段错误

来自分类Dev

malloc导致C中的分段错误

来自分类Dev

C程序中的段错误,malloc调用

来自分类Dev

C ++,逐行读取文本文件后,vector中出现错误

来自分类Dev

尝试使用strtok和malloc但仍然出现错误,并且我看不到错误消息

来自分类Dev

尝试使用链表C ++时出现错误

来自分类Dev

程序尝试为结构的指针成员分配malloc时出现分段错误

来自分类Dev

C#登录系统出现文本文件错误

来自分类Dev

C#登录系统出现文本文件错误

来自分类Dev

调试从服务器读取文本文件的C#代码中的相关错误

来自分类Dev

从文本文件将字符串读取到向量数组中的Char错误C ++

来自分类Dev

是否可以正确读取C#中BOM错误的文本文件?

来自分类Dev

C# 错误:OutOfMemoryException - 读取大文本文件并从字典中替换

来自分类Dev

尝试在C中获取文件扩展名时出现分段错误错误

Related 相关文章

  1. 1

    尝试释放malloc时出现错误

  2. 2

    从 C 中的文本文件读取时出现意外错误

  3. 3

    尝试:为什么出现malloc错误

  4. 4

    C ++中的Malloc错误?

  5. 5

    有没有办法读取文本文件并将其保存在 C 中的动态字符数组中,然后尝试并获得 'malloc(): memory Corruption'

  6. 6

    尝试从C中的文本文件读取信息

  7. 7

    尝试从邮筒读取时出现C读取文件错误87

  8. 8

    尝试从邮筒读取时出现C读取文件错误87

  9. 9

    读取文本文件错误C

  10. 10

    读取文本文件时C程序中的分段错误

  11. 11

    从 c 中的文本文件读取浮点数时的错误值

  12. 12

    Java在尝试读取文本文件时遇到运行时错误

  13. 13

    尝试创建文本文件时出现参数Null异常错误

  14. 14

    C ++中向量上的Malloc错误

  15. 15

    malloc导致C中的分段错误

  16. 16

    使用malloc的C中的分段错误

  17. 17

    malloc导致C中的分段错误

  18. 18

    C程序中的段错误,malloc调用

  19. 19

    C ++,逐行读取文本文件后,vector中出现错误

  20. 20

    尝试使用strtok和malloc但仍然出现错误,并且我看不到错误消息

  21. 21

    尝试使用链表C ++时出现错误

  22. 22

    程序尝试为结构的指针成员分配malloc时出现分段错误

  23. 23

    C#登录系统出现文本文件错误

  24. 24

    C#登录系统出现文本文件错误

  25. 25

    调试从服务器读取文本文件的C#代码中的相关错误

  26. 26

    从文本文件将字符串读取到向量数组中的Char错误C ++

  27. 27

    是否可以正确读取C#中BOM错误的文本文件?

  28. 28

    C# 错误:OutOfMemoryException - 读取大文本文件并从字典中替换

  29. 29

    尝试在C中获取文件扩展名时出现分段错误错误

热门标签

归档