cout <<棘手的运算符重载 - 转储结构的字节数
cout << tricky operator overloading - dumping bytes of a structure
可能重复:
c++中与cout混淆的char指针
给定您想要转储字节的任何结构,一种方法是在C++中实现它,如下所示:
void print_bytes(myst *my_struct)
{
char *ptr = (char *)my_struct;
cout << std::hex;
for (size_t i = 0; i < sizeof(*my_struct); i++) {
cout << ptr + i << ": " << ptr[i];
// similar to printf("%p: 0x%x", ptr + i, ptr[i]) right?
}
}
但是上面打印了地址和值的垃圾。为什么?
实际上,您的代码有几个问题。正如Omair所指出的,一个是ptr是一个char指针,所以cout假设它指向一个以null结尾的字符串。
第二个问题,正如Omair已经指出的那样,是ptr[i]是一个字符,将被打印为ASCII字形,而不是字符的值。解决方案是将其转换为内部
另一个问题是数据的类型。由于您声明ptr指向char而不是无符号char,因此这些值将进行符号扩展。任何大于7F的值都将显示为FFFFFF xx(继续FF的数量取决于编译器/环境中"int"的大小),因为它在打印时会从有符号的char转换为无符号的int。
最后一个问题(Omair的解决方案)是,现代编译器(例如g++-Wall)会抱怨在void指针上进行数学运算。因此,在将ptr转换为void指针之前,必须先进行数学运算,方法是将ptr+i封装在parens中。
完整的校正程序如下所示。
void print_bytes(myst *my_struct)
{
unsigned char *ptr = (unsigned char *)my_struct;
cout << std::hex;
for (size_t i = 0; i < sizeof(*my_struct); i++) {
cout << (const void *) (ptr + i) << ": " << (unsigned int) ptr[i] << "n";
}
}
cout
在函数上与printf并不完全相似。要理解这里的陷阱,您需要了解<<
运算符的不同重载函数。
我们有:
ostream& operator<< (short val);
ostream& operator<< (const void* val); // prints address given a pointer
ostream& operator<< (ostream& out, const char* s ); // prints a null-terminated string
ostream& operator<< (ostream& out, const signed char* s );
ostream& operator<< (ostream& out, const unsigned char* s );
现在,我们已经对my_struct
到char *
进行了类型转换,这样我们就可以逐字节打印它。但这改变了cout
的含义,它现在需要一个以null结尾的字符串,并打印字符,这些字符是垃圾。因此,需要显式的类型转换。此外,ptr[i]
是char
,因此它只打印值的单个字符。
修复:
cout << (const void *) ptr + i << ": " << (unsigned int) ptr[i];
相关文章:
- 分段故障(堆芯转储)矢量
- Cppcheck生成xml转储文件
- 如何找出GDB的SIGTRAP核心转储的根本原因
- C++映射分割错误(核心转储)
- 在c++中初始化矩阵时出现分段错误(核心转储)
- 在c++中键入向量中的所有值后,得到分段错误(核心转储)
- 浮点异常(核心转储)#694457
- 分段错误(核心转储)但无法弄清楚
- 链接到libkcapi时没有核心转储
- 检测到堆栈粉碎:已终止 中止(核心已转储)
- 正在处理故障(堆芯转储)
- 分段错误(核心转储) - 使用 SavedModel 的 Tensorflow C++ API 进行推断
- 我不知道为什么这段代码会让核心被转储?
- C++运行时错误与快速排序算法抛出堆栈转储错误
- 在基数排序中,我得到 munmap_chunk():无效指针和中止(核心转储).为什么?
- C++指针无法在函数外部传递值和分段错误(核心转储)错误
- cygwin_exception::open_stackdumpfile:将堆栈跟踪转储到 class4.exe.sta
- C++快速将 int 数组内容转储到文本文件中
- 合并排序:分段错误核心转储
- WinDbg 不显示某些小型转储文件的完整堆栈跟踪