这是我的推送功能
void push(struct Map *map, struct Location location){
struct Node *temp = map->front;
temp->loc = location; //this line causes the error
temp->next = NULL;
if(map->rear == NULL) { // if queue empty
map->front = temp; // First NODE
map->rear = map->front;
}else{// if there is stuff in the queue
map->rear->next = temp;
map->rear = temp;
// Insert End
}
free(temp);
}
我收到此错误
==2301== Invalid write of size 8
==2301== at 0x401148: push (3146.c:239)
==2301== by 0x400DE7: findEntrance (3146.c:164)
==2301== by 0x400820: main (3146.c:55)
==2301== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==2301==
我正在对排列成迷宫的字符网格进行广度优先搜索。我一直无法避免内存泄漏,所以我终于发现使用 malloc 有帮助,但我不明白为什么我不能在没有段错误的情况下执行此数据分配
另一种方法是不释放它并导致内存泄漏,我认为这不是一个可接受的解决方案。我的逻辑哪里错了?
下面是整个程序
#include <stdio.h>
#include <stdlib.h>
struct Location;
struct Map;
struct Node;
//function names seem to self describe
void pathFinder(struct Map*);
void findEntrance(struct Map*);
void readInMap(struct Map*);
void printMap(struct Map*);//to screen
/* Q funcs */
void pop(struct Map*);
void push(struct Map*, struct Location);
struct Location {// simple location type
int x;
int y;
};
struct Node {//standard linked list node
struct Location loc;
struct Node *next;
};
struct Map { //variable size encompassing array, and dimension variables
char arr[100][100];
int xLength;//dimensions
int yLength;
int complete;
struct Node *rear;//Q pointers
struct Node *front;
struct Node *currLoc; //temp for BFS
struct Location entrance;
};
int main(){
struct Map map;//the one map to rule them all
map.xLength = 0;//map dimensions
map.yLength = 0;
map.front = NULL; // queue pointers init
map.rear = NULL;
map.currLoc = NULL;
map.entrance.x = 0;
map.entrance.y = 0;
map.complete = 0;
readInMap(&map);
findEntrance(&map);//start off by finding where to start
pathFinder(&map); // problem solver method
printMap(&map);
free(map.front);
free(map.rear);
free(map.currLoc);
return 0;
}
void pathFinder(struct Map *map){
int x;//should be the entrance already pushed from findEntrance
int y;
int done = 0;
struct Location temp;
temp.x = 0;// temp for pushing locations that are adjacent 0's
temp.y = 0;
while(map->front != NULL){
map->currLoc = map->front;//currLoc is just a copy so that we can pop the map location of currLoc from Q
pop(map);// pop so it cant be used twice in this loop
x = map->currLoc->loc.x;
y = map->currLoc->loc.y;
temp.x = 0;
temp.y = 0;
if(map->arr[y][x] == '0'){//protection of 1 values from replacement
map->arr[y][x] = 'X';//replace the array position loc w x
}
if(map->arr[y][x] == '0'){//protection of 1 values from replacement
map->arr[y][x] = 'X';//replace the array position loc w x
printf("test\n");
}
/* find adjacent 0's */
if((y < map->xLength)&&(map->arr[y+1][x] == '0')){
temp.x = x;
temp.y = y+1;
push(map, temp);
}
if((x < map->xLength)&&(map->arr[y][x+1] == '0')){
temp.x = x+1;
temp.y = y;
push(map, temp);
}
if((y > 0)&&(map->arr[y-1][x] == '0')){
temp.x = x;
temp.y = y-1;
push(map, temp);
}
if((x > 0)&&(map->arr[y][x-1] == '0')){
temp.x = x-1;
temp.y = y;
push(map, temp);
}
if((x == 0)||(x == map->xLength)||(y == 0)||(y == map->yLength)){ //then its not on the edge
if((x != map->entrance.x)&&(y != map->entrance.y)){
map->front = NULL;
map->complete++;
}
}
}
}
void findEntrance(struct Map *map){
struct Location entrance;
int done = 0;
int y=0;//index of current row depth
int x=0;//index of current column depth
if (done == 0){
for (x=0;x<=map->xLength;x++){ // top row
if (map->arr[y][x] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
if (done == 0){
for(y=0;y<=map->yLength;y++){//down the right side
if (map->arr[y][map->xLength] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
if (done == 0){
for(x;x>=0;x--){//bottom row RtoL
if (map->arr[map->yLength][x] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
if (done == 0){
for(y;y>=0;y--){//up the left side
if (map->arr[y][0] == '0') {
entrance.x = x;
entrance.y = y;
done = 1;
}
}
}
map->entrance = entrance;
push(map, map->entrance);
}
void readInMap(struct Map *map){
FILE *fptr;
char c;
char file_name[20];
int i,j;
int rows;
int cols;
int x,y;
printf("Size\n");
printf("Rows:");
scanf("%i", &rows);
printf("Columns:");
scanf("%i", &cols);
map->xLength = cols-1; //[y][xLength]
map->yLength = rows-1; //[yLength][x]
for (x=0;x<100;x++){
for (y=0;y<100;y++){
map->arr[x][y] = '1';//whole array is 1
}
}
printf("Type in the name of the file containing the Field\n");
scanf("%s",file_name);
fptr=fopen(file_name, "r");
for (i = 0; i <= map->xLength; i++){
for (j = 0; j <= map->yLength; j++){
c=fgetc(fptr); //handles new line character and spaces
while ( !((c == '1') || (c =='0')) ) {
c=fgetc(fptr);
}
map->arr[i][j] = c;
}
}
printf("\n");
fclose(fptr);
}
void printMap(struct Map *map){
int y;//index of current row depth
int x;//index of current column depth
for (x=0;x<=map->xLength;x++){
for (y=0;y<=map->yLength;y++){//current pos (x,y)
printf("%c", map->arr[x][y]);
}
printf("\n");
}
if(map->complete != 0){
printf("\n An exit to the maze was found that is not the entrance\n");
}else{
printf("\n No exit was found \n");
}
}
void pop(struct Map *map){
if (map->front != NULL){//if not empty
if (map->front == map->rear){
map->rear = NULL;//if the line length is 1, empty it
map->front = NULL;
}else{
map->front = map->front->next;//next in line
}
}else{
map->rear = NULL;//empty out the queue
map->front = NULL;
}
}
void push(struct Map *map, struct Location location){
struct Node *temp = (struct Node*)malloc(sizeof(struct Node));
temp->loc = location;
temp->next = NULL;
if(map->rear == NULL) { // if queue empty
map->front = temp; // First NODE
map->rear = map->front;
}else{// if there is stuff in the queue
map->rear->next = temp;
map->rear = temp;
// Insert End
}
free(temp);
}
最佳答案
当Map
为空时,front
和rear
都为NULL。因此 temp->loc
取消引用 NULL 指针。
您需要malloc
新节点并将其添加到列表中。此外,您不想在此处free
,因为这会释放您刚刚添加到列表中的内存。
void push(struct Map *map, struct Location location){
struct Node *temp = malloc(sizeof(struct Node));
temp->loc = location;
temp->next = NULL;
if(map->rear == NULL) { // if queue empty
map->front = temp; // First NODE
map->rear = map->front;
}else{// if there is stuff in the queue
map->rear->next = temp;
map->rear = temp;
// Insert End
}
}
在 pop
中是您要释放内存的位置:
void pop(struct Map *map){
struct Node *temp = map->front;
if (map->front != NULL){//if not empty
if (map->front == map->rear){
map->rear = NULL;//if the line length is 1, empty it
map->front = NULL;
}else{
map->front = map->front->next;//next in line
}
free(temp);
}else{
map->rear = NULL;//empty out the queue
map->front = NULL;
}
}
关于c - 在 c 中为队列推送中的临时分配内存时出错,来自 valgrind 的写入大小为 8 无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35323251/