C:分段错误,原因以及如何修复
C: Segmentation fault, why and how to fix
我目前正在学习如何编程,我很确定我的代码充满了错误。
我在执行这段代码时遇到了分段错误,我不知道为什么。
#include <stdio.h>
#include <libxml/parser.h>
#include <string.h>
#include <stdlib.h>
typedef struct
{
int ac; /**< The player armor class. */
char *class; /**< The player class. */
char *cname; /**< The player character name. */
int cp; /**< The player money (copper pieces, 100 CP = 1 GP). */
int gp; /**< The player money (gold pieces). */
int hp; /**< The player hit points. */
char *name; /**< The player name. */
int sp; /**< The player money (silver pieces, 10 SP = 1 GP). */
} player_t;
void parsePlayer(xmlDocPtr doc, xmlNodePtr node){
int i = 1;
player_t players[3];
xmlNodePtr cur;
node = node->xmlChildrenNode;
while(node!=NULL){
if (!xmlStrcmp(node->name, (const xmlChar *) "player"))
{
players[i].name = (char *) xmlGetProp(node, (const xmlChar *)"name");
printf("player %d name: %s\n", i, players[i].name);
cur = node->xmlChildrenNode;
players[i].ac = strtol((char *) xmlNodeListGetString(doc, cur->xmlChildrenNode, 1),NULL,10);
i++;
}
node = node->next;
}
}
void parsePlayers(xmlDocPtr doc){
xmlNodePtr node;
node = xmlDocGetRootElement(doc);
node = node->xmlChildrenNode;
while(node!=NULL){
if (!xmlStrcmp(node->name, (const xmlChar *) "players")){
parsePlayer(doc, node);
}
node = node->next;
}
}
int main(int argc, char const *argv[]) {
xmlDocPtr doc = xmlParseFile(argv[1]);
if (doc != NULL) printf("DEBUG: File parsed.\n");
else {
fprintf(stderr,"Unable to parse the document \n");
return 1;
}
parsePlayers(doc);
return 0;
}
代码显示:
DEBUG: File parsed.
player 1 name: Camille /* correct */
Segmentation Fault
我已经尝试寻找答案,但似乎我还不够先进,无法理解它们:/.
这是学校的一个项目(我必须填写几个 player_t 结构)。
我不认为错误来自 XML,因此无需在此处 post。
几天来我一直被这个错误困扰,我很想知道如何纠正它。
感谢阅读 :).
编辑:感谢您的回答,gdb 说:
Program received signal SIGSEGV, Segmentation fault.
__GI_____strtol_l_internal (nptr=0x0, endptr=0x0, base=10, group=<optimized out>,
loc=0x7ffff7a0f560 <_nl_global_locale>) at ../stdlib/strtol_l.c:292
292 ../stdlib/strtol_l.c: no such file or directory.
我不知道这是什么意思:(。
编辑 2:好的,错误确实来自 xml,这里是:
<ddg name="The frozen cave">
<date>
<day>01</day>
<month>09</month>
<year>2019</year>
</date>
<dmname>Pierre</dmname>
<players>
<player name="Camille">
<ac>5</ac>
<class>Thief</class>
<cname>Camigolas</cname>
<hp>4</hp>
<money>
<cp>10</cp>
<gp>10</gp>
<sp>10</sp>
</money>
</player>
<player name="Jean">
<ac>4</ac>
<class>Fighter</class>
<cname>Jeragorn</cname>
<hp>8</hp>
<money>
<cp>3</cp>
<gp>1</gp>
<sp>2</sp>
</money>
</player>
<player name="Paul">
<ac>5</ac>
<class>Cleric</class>
<cname>Paumli</cname>
<hp>6</hp>
<money>
<cp>9</cp>
<gp>5</gp>
<sp>9</sp>
</money>
</player>
</players>
</ddg>
我尝试了几种方法,最后发现播放器的 xmlChildrenNode 是文本。
我想我只需要循环直到找到我想要的元素,但是有人知道为什么它是 returns 文本吗? (我只是 printf cur->name 来发现)。
谢谢大家的回答:)!
nptr=0x0
可能意味着 strtol
(或者更确切地说是 strtol
调用的函数)是在参数 nptr
设置为 [=14= 的情况下调用的].参数 nptr
很可能指向一个有效的字符串,但事实并非如此。
这可能意味着 xmlNodeListGetString()
returns 零或 NULL
,具体取决于您喜欢如何调用该值。
解析外部文件时,您应该始终对文件内容进行错误检查。
我猜 cur->xmlChildrenNode
没有您期望的价值,但如果没有更多信息很难说。
顺便说一下,c
是那些具有从零开始的数组的语言之一,因此您应该有 int i = 0
。 (基于 1 的数组是 邪恶的 。)不要通过在 players[0]
.
处具有虚拟元素来模拟基于 1 的数组来成为异教徒
I've tried several things and ended up discovering that the xmlChildrenNode of player is text. I guess i just need to loop until i find the element i want but does anyone knows why it returns text
XML 文件中元素之间的所有空格都很重要。 节点将有 11 个子节点:
- 一个文本节点,紧跟在
之后的换行符和之前的空格
- 一个元素节点,它是
(它将有一个文本节点子节点,ac 值)
- 一个文本节点, 之后的换行符和
之前的空格
- 一个元素节点,即
- 等....
所以您在 下看到的第一个 "text" 子项是出现在 之前的换行符和空格。
您可能希望将 XML_PARSE_NOBLANKS 传递给 xmlParseFile,它告诉解析器像这样跳过 "in-between" 空格。然后 将有 子级,然后是 子级等,中间没有文本节点。
我目前正在学习如何编程,我很确定我的代码充满了错误。
我在执行这段代码时遇到了分段错误,我不知道为什么。
#include <stdio.h>
#include <libxml/parser.h>
#include <string.h>
#include <stdlib.h>
typedef struct
{
int ac; /**< The player armor class. */
char *class; /**< The player class. */
char *cname; /**< The player character name. */
int cp; /**< The player money (copper pieces, 100 CP = 1 GP). */
int gp; /**< The player money (gold pieces). */
int hp; /**< The player hit points. */
char *name; /**< The player name. */
int sp; /**< The player money (silver pieces, 10 SP = 1 GP). */
} player_t;
void parsePlayer(xmlDocPtr doc, xmlNodePtr node){
int i = 1;
player_t players[3];
xmlNodePtr cur;
node = node->xmlChildrenNode;
while(node!=NULL){
if (!xmlStrcmp(node->name, (const xmlChar *) "player"))
{
players[i].name = (char *) xmlGetProp(node, (const xmlChar *)"name");
printf("player %d name: %s\n", i, players[i].name);
cur = node->xmlChildrenNode;
players[i].ac = strtol((char *) xmlNodeListGetString(doc, cur->xmlChildrenNode, 1),NULL,10);
i++;
}
node = node->next;
}
}
void parsePlayers(xmlDocPtr doc){
xmlNodePtr node;
node = xmlDocGetRootElement(doc);
node = node->xmlChildrenNode;
while(node!=NULL){
if (!xmlStrcmp(node->name, (const xmlChar *) "players")){
parsePlayer(doc, node);
}
node = node->next;
}
}
int main(int argc, char const *argv[]) {
xmlDocPtr doc = xmlParseFile(argv[1]);
if (doc != NULL) printf("DEBUG: File parsed.\n");
else {
fprintf(stderr,"Unable to parse the document \n");
return 1;
}
parsePlayers(doc);
return 0;
}
代码显示:
DEBUG: File parsed.
player 1 name: Camille /* correct */
Segmentation Fault
我已经尝试寻找答案,但似乎我还不够先进,无法理解它们:/.
这是学校的一个项目(我必须填写几个 player_t 结构)。
我不认为错误来自 XML,因此无需在此处 post。
几天来我一直被这个错误困扰,我很想知道如何纠正它。
感谢阅读 :).
编辑:感谢您的回答,gdb 说:
Program received signal SIGSEGV, Segmentation fault.
__GI_____strtol_l_internal (nptr=0x0, endptr=0x0, base=10, group=<optimized out>,
loc=0x7ffff7a0f560 <_nl_global_locale>) at ../stdlib/strtol_l.c:292
292 ../stdlib/strtol_l.c: no such file or directory.
我不知道这是什么意思:(。
编辑 2:好的,错误确实来自 xml,这里是:
<ddg name="The frozen cave">
<date>
<day>01</day>
<month>09</month>
<year>2019</year>
</date>
<dmname>Pierre</dmname>
<players>
<player name="Camille">
<ac>5</ac>
<class>Thief</class>
<cname>Camigolas</cname>
<hp>4</hp>
<money>
<cp>10</cp>
<gp>10</gp>
<sp>10</sp>
</money>
</player>
<player name="Jean">
<ac>4</ac>
<class>Fighter</class>
<cname>Jeragorn</cname>
<hp>8</hp>
<money>
<cp>3</cp>
<gp>1</gp>
<sp>2</sp>
</money>
</player>
<player name="Paul">
<ac>5</ac>
<class>Cleric</class>
<cname>Paumli</cname>
<hp>6</hp>
<money>
<cp>9</cp>
<gp>5</gp>
<sp>9</sp>
</money>
</player>
</players>
</ddg>
我尝试了几种方法,最后发现播放器的 xmlChildrenNode 是文本。
我想我只需要循环直到找到我想要的元素,但是有人知道为什么它是 returns 文本吗? (我只是 printf cur->name 来发现)。
谢谢大家的回答:)!
nptr=0x0
可能意味着 strtol
(或者更确切地说是 strtol
调用的函数)是在参数 nptr
设置为 [=14= 的情况下调用的].参数 nptr
很可能指向一个有效的字符串,但事实并非如此。
这可能意味着 xmlNodeListGetString()
returns 零或 NULL
,具体取决于您喜欢如何调用该值。
解析外部文件时,您应该始终对文件内容进行错误检查。
我猜 cur->xmlChildrenNode
没有您期望的价值,但如果没有更多信息很难说。
顺便说一下,c
是那些具有从零开始的数组的语言之一,因此您应该有 int i = 0
。 (基于 1 的数组是 邪恶的 。)不要通过在 players[0]
.
I've tried several things and ended up discovering that the xmlChildrenNode of player is text. I guess i just need to loop until i find the element i want but does anyone knows why it returns text
XML 文件中元素之间的所有空格都很重要。
- 一个文本节点,紧跟在
之后的换行符和 之前的空格 - 一个元素节点,它是
(它将有一个文本节点子节点,ac 值) - 一个文本节点, 之后的换行符和
- 一个元素节点,即
- 等....
所以您在
您可能希望将 XML_PARSE_NOBLANKS 传递给 xmlParseFile,它告诉解析器像这样跳过 "in-between" 空格。然后