我试图显示特定地址的内容,给定该地址的char *。到目前为止,我尝试使用以下实现
int mem_display(char *arguments) {
int address = *arguments;
int* contents_pointer = (int*)address;
int contents = *contents_pointer;
printf("Address %p: contents %16x\n", contents_pointer, contents);
}
但我一直得到一个"分段错误(Core Dumped)"错误。我试图制作一个虚拟指针来测试
char foo = 6;
char *bar = &foo;
但错误仍然存在
答案 0 :(得分:5)
我发现很难解释问题是什么,因为代码中几乎每一行都是错误的。
这就是我要做的事情:
void mem_display(const void *address) {
const unsigned char *p = address;
for (size_t i = 0; i < 16; i++) {
printf("%02hhx", p[i]);
}
putchar('\n');
}
答案 1 :(得分:2)
您需要迭代地址的内容,并分别打印每个内容,直到达到16.示例代码:
#include <stdio.h>
void mem_display(unsigned char *arguments) {
printf("Address %p: ", arguments);
int i =0;
unsigned char* byte_array = arguments;
while (i < 16)
{
printf("%02hhx", byte_array[i]);
i++;
}
}
int main(void) {
unsigned char foo = 6;
unsigned char *bar = &foo;
mem_display(bar);
return 0;
}
输出:
地址0x7ffe5b86a777:0677A7865BFE7F000060054000000000
答案 2 :(得分:2)
如果您已经有一个指向要打印内容的地址的指针,您可以直接将其提供给printf
,如下所示:
void print_16_bytes_at(const char *arguments)
{
printf("Address %p: contents", (const void *)arguments);
for (int i = 0; i < 16; i++)
printf(" %02x", (unsigned int)(unsigned char)arguments[i]);
putchar('\n');
}
如果arguments
没有指向要打印内容的内存,那么我就不明白它实际上是什么 我需要你更好地解释。
以上示例代码的注释:
%p
而不引发未定义的行为,您必须明确地将指针强制转换为[const] void *
,除非它已经是[const] void *
。因为printf
接受可变数量的参数,所以编译器不知道其参数的预期类型,因此它不会为您插入此转换,就像使用带{{{}的普通函数一样。 1}}参数。[const] void *
强制(unsigned int)(unsigned char)
从char
读取的内容为零扩展,而不是符号扩展为arguments[i]
的宽度。如果你不这样做,那么从0x80开始的值可能会打印出一堆领先的F(例如unsigned int
),这可能不是你想要的。如果在提供的地址上没有16字节的可读内存,这仍然会出现段错误。在你的例子中
ffffff80
只保证char foo = 6;
print_16_bytes_at(&foo);
地址的可读内存的一个字节。 (它可能适用于您可以轻松获得的任何计算机,但它仍然允许按照C标准的字母崩溃。)
答案 3 :(得分:1)
原始代码存在一些问题。首先,它将传递的指针指向两次。它将arguments
视为指向要打印内容的指针。由于arguments
是指向char的指针,因此这绝对是错误的。 (它最终将从一个非常小的地址读取,这是一个明确的分段违规或大多数架构上的其他崩溃。)
其次,除非您知道arguments
指针已正确对齐,否则通过该指针加载int
可能会因未对齐的访问而崩溃。 (这可能会显示为分段违规。)您可能无法假设此例程正确对齐。
第三,如果你需要打印16个字节,那么int
(通常)只会得到4个或8个字节。使用标准打印例程来连接所有部分比逐字节循环写入更加棘手。 (有关此类循环的示例,请参阅上面的答案。)
答案 4 :(得分:1)
我认为你要么过于复杂,要么你没有足够的描述实际输入是什么。它指向指针吗?
无论如何,要用一些指向内存的指针以简单的方式做到这一点,你可以像这样做(C-like C ++,抱歉,在web cpp.sh网上快点完成):
<your.package.name.ExtendedBottomNavigationView android:id="@id/bottomMenu" style="@style/bottomMenu"/>
输出:
#include <iostream>
const unsigned char fakeData[] = { 1, 13, 0, 255 };
void mem_display(
std::FILE* file,
const unsigned char* memoryPtr,
const size_t size)
{
fprintf(file, "Address %p:", (const void*)memoryPtr);
for (size_t i = 0; i < size; ++i) fprintf(file, " %02hhx", memoryPtr[i]);
fprintf(file, "\n");
}
int main()
{
mem_display(stdout, fakeData, 4);
}
要打印16个字节,只需更改size参数。
我不能想到具有16个字节的普通类型,所以我不确定为什么要尝试将其打印为单个数字,通常在调试器中使用如上所述的单字节输出(直到用户请求不同大小的单位)。
答案 5 :(得分:0)
很长一段时间我都使用以下功能打印内存区域的内容:
/*************************************************************/
/**
* Function to dump memory area
* \param address start address
* \param len length of memory area
*/
/*************************************************************/
void dump( void* address, int len ) noexcept{
int i;
printf("dump from 0x%lX (%d bytes)\n",(long)address, len);
printf("=============================================");
for(i=0; i<len; i++){
if(i%16==0){printf("\n");}
printf("%2X ",(*((char*)address+i))&0xFF);
}
printf("\n=============================================\n");
}
对于C程序,请删除noexcept
关键字。