c - C 中的 Valgrind 错误:使用结构、链表和指针。大小为 1 的无效读取和进程以信号 11 的默认操作终止
问题描述
所以我正在编写一个应该链接链表中的数据结构的程序,但我总是得到 valgrind 错误:
Invalid read of size 1
and
Process terminating with default action of signal 11 (SIGSEGV)
Access not within mapped region at address 0x0
代码的很大一部分已经给了我,我只需要完成它。这是我被要求做的:
读取道路: 编写代码以读取道路并将有关道路的信息连接到城市。道路由起点城市和终点城市指定,两者均以城市名称定义,后跟道路长度。首先,需要为每条道路确定代表起点城市和终点城市的结构。使用 road.h 中的函数 new_road() 创建 Road 结构。 new_road() 返回的结构应添加到道路所在城市的道路列表中,类似于将 City 结构添加到城市名单。请注意,您只能对 roadplan.c 进行更改
这是程序的主文件,我写的部分前面有一个 FIXME 注释:
错误信息一直在底部
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "salloc.h"
#include "city.h"
#include "road.h"
#define MAX_STRING_LENGTH 100
/*
* Build the map datastructure
*/
static City *create_map (FILE *data_file)
{
int num_of_cities, i = 0;
int num_of_roads = 0;
City *map = NULL;
/* Read in city-names */
fscanf (data_file, "%d", &num_of_cities);
for (i = 0; i < num_of_cities; i++)
{
char city_name[MAX_STRING_LENGTH + 1];
City *city;
City *c;
fscanf (data_file, "%s", city_name);
if (find_city (map, city_name) != NULL)
{
fprintf (stderr, "City %s already on the map\n", city_name);
delete_map (map);
exit (EXIT_FAILURE);
}
city = new_city (safe_strdup (city_name));
if (map == NULL)
/* This is the first city of the map */
map = city;
else {
/* Find last of city list */
c = map;
while (c->next) c = c->next;
/* And append new city there */
c -> next = city;
}
}
/* FIXME
* Read number of roads
* For each road:
* Read origin city name, destination city name and length
* Find pointers to orgin city structure and destination city structure
* using the function find_city()
* Create new road structure using new_road() function
* Add it to the list of roads of the origin city.
*/
/* Read in number-of roads */
fscanf (data_file, "%d", &num_of_roads);
/*read origin city name, destination city name and length for each road
*/
for (i = 0; i < num_of_roads; i++)
{
City road_origin[MAX_STRING_LENGTH + 1]={{0}}, road_destination[MAX_STRING_LENGTH + 1]={{0}};
unsigned int length = 1;
Road *road;
Road *r;
City *city;
fscanf (data_file, "%s %s %u", road_origin->name, road_destination->name, &length);
if (find_city (map, road_origin->name) == NULL)
{
fprintf (stderr, "Cannot find city %s on the map\n", road_origin->name);
exit (EXIT_FAILURE);
}
if (find_city (map, road_destination->name) == NULL)
{
fprintf (stderr, "Cannot find city %s on the map\n", road_destination->name);
exit (EXIT_FAILURE);
}
road = new_road(road_origin,road_destination, length);
/*Create new road structure using new_road() function
* Add it to the list of roads of the origin city.
*/
for (city = map; city != NULL; city = city->next)
{
if (strcmp(city->name,road_origin->name)==0)
{
road_origin->name = city->name;
if (city->roads == NULL)
city->roads=road;/*first road of that city*/
else
{
r=road;
while (r->next) r = r->next;
r -> next = road;
}
}
if (strcmp(city->name,road_destination->name)==0)
{
road_destination->name = city->name;
}
}
}
return map;
}
/*
* Locate city with name city_name on the map
*/
City *find_city (City *list_of_cities, char *city_name)
{
City *c = list_of_cities;
while (c != NULL)
{
if (strcmp (c->name, city_name) == 0)
return c;
c = c->next;
}
return NULL;
}
/*
* Delete a map
*/
static void delete_map (City *map)
{
City *map_copy;
while (map != NULL)
{
map_copy = map;
map = map->next;
delete_city (map_copy);
}
}
这是给定的 .c 和 .h 文件
道路.c:
#include <stdlib.h>
#include "road.h"
#include "salloc.h"
Road *new_road (City *origin, City *destination, int length)
{
Road *road = safe_malloc (sizeof (Road));
road->origin = origin;
road->destination = destination;
road->length = length;
road->next = NULL;
return road;
}
void delete_road (Road *road)
{
if (road != NULL)
free (road);
}
void delete_roads (Road *roads)
{
Road *roads_copy;
while (roads)
{
roads_copy = roads;
roads = roads->next;
delete_road (roads_copy);
}
}
道路.h:
#ifndef _ROAD_H_
#define _ROAD_H_
typedef struct road Road;
#include "city.h"
struct road
{
City *origin;
City *destination;
unsigned int length;
Road *next;
};
Road *new_road (City *origin, City *destination, int length);
void delete_road (Road *road);
void delete_roads (Road *roads);
#endif /* _ROAD_H_ */
城市.c:
#include <stdlib.h>
#include "city.h"
#include "salloc.h"
City *new_city (char *name)
{
City *city = safe_malloc (sizeof (City));
city->name = name;
city->roads = NULL;
city->next = NULL;
return city;
}
void delete_city (City *city)
{
if (city != NULL)
{
delete_roads (city->roads);
free (city->name);
free (city);
}
}
城市.h:
#ifndef _CITY_H_
#define _CITY_H_
typedef struct city City;
#include "road.h"
struct city
{
char *name;
Road *roads;
City *next;
};
City *new_city (char *name);
void delete_city (City *city);
City *find_city (City *map, char *name);
#endif /*_CITY_H_ */
salloc.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static void *check_pointer (void *p)
{
if (p == NULL)
{
printf ("Error: out of memory!\n");
exit (1);
}
return p;
}
void *safe_malloc (size_t size)
{
return check_pointer (malloc (size));
}
char *safe_strdup (const char *string)
{
return strcpy (safe_malloc (strlen (string) + 1), string);
}
salloc.h:
#include <stdlib.h>
/* These functions provide a way to safely
* allocate memory
*/
void *safe_malloc (size_t size);
char *safe_strdup (const char *string);
这是我收到的错误消息:
Non-zero exitcode 139
********** runguard stderr follows **********
/usr/bin/runguard: warning: command terminated with signal 11
********** valgrind output follows **********
Memcheck, a memory error detector
Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
Command: /var/lib/domjudge/judgings/ce-codeserver/c8-s38522-j44168/testcase001/execdir/program_d datafile
Invalid read of size 1
at 0x4C2E2B4: __strcmp_sse42 (vg_replace_strmem.c:852)
by 0x400B91: find_city (roadplan.c:27)
by 0x400DEB: create_map (roadplan.c:123)
by 0x401246: main (roadplan.c:280)
Address 0x0 is not stack'd, malloc'd or (recently) free'd
Process terminating with default action of signal 11 (SIGSEGV)
Access not within mapped region at address 0x0
at 0x4C2E2B4: __strcmp_sse42 (vg_replace_strmem.c:852)
by 0x400B91: find_city (roadplan.c:27)
by 0x400DEB: create_map (roadplan.c:123)
by 0x401246: main (roadplan.c:280)
If you believe this happened as a result of a stack
overflow in your program's main thread (unlikely but
possible), you can try to increase the size of the
main thread stack using the --main-stacksize= flag.
The main thread stack size used in this run was 16777216.
HEAP SUMMARY:
in use at exit: 176 bytes in 11 blocks
total heap usage: 11 allocs, 0 frees, 176 bytes allocated
LEAK SUMMARY:
definitely lost: 0 bytes in 0 blocks
indirectly lost: 0 bytes in 0 blocks
possibly lost: 0 bytes in 0 blocks
still reachable: 176 bytes in 11 blocks
suppressed: 0 bytes in 0 blocks
Rerun with --leak-check=full to see details of leaked memory
For lists of detected and suppressed errors, rerun with: -s
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
解决方案
推荐阅读
- javascript - 如何水平对齐弹性框中的一项?
- java - 无法解析 GroovyClassLoader
- javascript - 为什么这种平面和排序方法的组合会返回子数组?
- django - 处理 AJAX POST 请求以在 django 中呈现模板
- node.js - 如何使用node.js将pdf保存在文件夹中
- java - JetBrains 学院关于将小数转换为给定基数的问题
- java - 如何使用 java 代码获取 Jira 执行结果
- python - 如何根据其令牌访问特定的日志条目?
- c++ - 如何从 popen 获取未找到和权限错误
- reactjs - 当我们在 NextJs 应用程序中更改路由时,后续页面是否也可以抓取 (SEO)?