我试图让我的代码从内容涉及的文本文件中读取:(文本文件称为 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;
您无法知道是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] 删除。
我来说两句