读取xml时出现越界错误
Address Out of bounds error when reading xml
当使用libxml解析文件时,我得到一个奇怪的段错误。这段代码以前在我将其编译为32位应用程序时可以工作。我把它改成64位的应用程序,它停止工作了。
seg错误出现在"if (xmlStrcmp(cur->name, (const xmlChar *)"服务器"))"
cur->name是一个const xmlChar *,它指向一个地址,表明它超出了边界。但是当我调试并进入内存位置时,数据是正确的。
int XmlGetServers()
{
xmlDocPtr doc;
xmlNodePtr cur;
doc = xmlParseFile("Pin.xml");
if (doc == NULL)
{
std::cout << "n Pin.xml not parsed successfully." << std::endl;
return -1;
}
cur = xmlDocGetRootElement(doc);
if (cur == NULL)
{
std::cout << "n Pin.xml is empty document." << std::endl;
xmlFreeDoc(doc);
return -1;
}
if (xmlStrcmp(cur->name, (const xmlChar *) "servers"))
{
std::cout << "n ERROR: Pin.xml of the wrong type, root node != servers." << std::endl;
xmlFreeDoc(doc);
return -1;
}
}
在初始化cur之前,name参数是
Name : name
Details:0xed11f72000007fff <Address 0xed11f72000007fff out of bounds>
初始化cur后,name参数为
Name : name
Details:0x64c43000000000 <Address 0x64c43000000000 out of bounds>
引用的XML文件
<?xml version="1.0"?>
<servers>
<server_info>
<server_name>Server1</server_name>
<server_ip>127.0.0.1</server_ip>
<server_data_port>9000</server_data_port>
</server_info>
<server_info>
<server_name>Server2</server_name>
<server_ip>127.0.0.1</server_ip>
<server_data_port>9001</server_data_port>
</server_info>
</servers>
系统:
OS: Redhat Enterprise Linux 6.4 64位
GCC: 4.4.7-3
包:libxml2 2.7.6 - 8. el6_3.4.x86_64
我把你的代码,原样,并添加:
#include <libxml/parser.h>
#include <iostream>
然后将函数重命名为main(),并在x86-64 Fedora 22上编译它,该版本有libxml2 2.9.2
结果代码使用示例文件成功运行,没有段错误。甚至valgrind也没有发现内存访问冲突。作为证明,生成的简化的空间日志如下:
stat("Pin.xml", {st_mode=S_IFREG|0644, st_size=362, ...}) = 0
stat("Pin.xml", {st_mode=S_IFREG|0644, st_size=362, ...}) = 0
stat("Pin.xml", {st_mode=S_IFREG|0644, st_size=362, ...}) = 0
open("Pin.xml", O_RDONLY) = 3
lseek(3, 0, SEEK_CUR) = 0
read(3, "<?xml version="1.0"?>nn<servers>nn<server_info>nn <server_name>Server1</server_name>nn <server_ip>127.0.0.1</server_ip> nn <server_data_port>9000</server_data_port> nn</server_info>nn<server_info>nn <server_name>Server2</server_name> nn <ser"..., 8192) = 362
read(3, "", 7830) = 0
getcwd("/tmp", 1024) = 5
close(3) = 0
exit_group(0) = ?
+++ exited with 0 +++
虽然这是Fedora的libxml2和gcc稍微新了一点,但是这个区别并不重要。这里的答案是,这里显示的代码没有任何问题。我看不出有什么问题。
但它显然是一个更大的应用程序的一部分,你的内存损坏发生在你的应用程序的其他部分,只有当你的应用程序执行到这部分时,它才会表现出来。
c++的问题是,仅仅因为代码在某个特定点崩溃,并不意味着这一行代码就是问题所在。想出一个简单的例子应该不难:
#include <iostream>
#include <cstring>
int main()
{
char foo[3];
strcpy(foo, "FoobarbazXXXXXXXXXXXXXXXXXXXXXX");
for (int i=0; i<100; i++)
std::cout << i << std::endl;
return 0;
}
这里的错误显然发生在strcpy
行。但是代码将正常运行,并打印从0到99的100个数字,并在main()返回时崩溃。但是,很明显,"return 0"并不是错误所在。
这与您的应用程序中发生的情况类似。在某些时候会发生某种内存损坏,在您的代码试图解析XML文件之前,这不会对代码执行产生实质性影响。
欢迎来到c++。
问题是我们在代码中使用了#pragma pack(1),这意味着DOMParser中的bool被压缩到1字节,而Xerces没有#pragma pack,而是获得4字节的默认打包。
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- C++:成员的越界声明必须是纯虚函数的定义错误
- C++不给出越界错误.有没有办法强制编译器检查而不是未定义的行为?
- 分段错误:为什么这里的数组索引越界了
- 是什么导致了数组越界运行时错误?
- 数组越界或错误等于 nullptr?C++
- 裁剪图像会导致越界错误
- 为什么这种越界访问没有段错误?
- 为什么 Cppcheck 找不到这个明显的数组越界错误
- OpenCV 32位图像越界错误
- 为什么 CppCheck 会为此静态 const 数组提供越界访问错误
- 读取xml时出现越界错误
- 段错误:C语言指针的地址越界
- 为什么当我访问数组的越界元素时没有收到运行时错误?