如何在 C 中用内存地址初始化一个 char 数组?
How do I initialize a char array with a memory address in C?
我在大二学习 C class,这个项目是关于处理指针和设计内存转储函数。所以我已经能够努力通过指针并获得要转储的开始和结束地址,甚至对其进行位掩码,我想用开始内存地址初始化一个 char 数组。我用存储屏蔽起始地址的同一个变量初始化它,但是当我打印数组时,它包含一个不同的内存地址。这是函数:
void memDump(void *base, int bytes)
{
unsigned char *begin;
begin = base;//beginning of range of memory
unsigned char *end;// ending range of memory
end = base + bytes;
int a, b;
long long int d=base;
d=d&0xFFFFF0; //trying to bitmask
long long int e=end;
e = e&0xFFFF0; //masked off the beginning and ending range
char c[16]={d}; //loop variables
printf("%x", c);
for (a=begin; a<=end; a+=16)
{
printf("\n%016X\n", d);
printf("%016X\n", a);
printf("%016X", e);
}
}
抱歉,我找不到类似的东西,这是我最后的选择。谢谢!
更新:感谢大家的洞察力,阅读更多关于 C 的内容和一些关于如何调试的文章帮助了我。
你不能 "initialize a char array" 一些 "memory address." 字符数组只能用字符初始化。
Whosebug不是给你做功课的,所以我会给你一些建议,然后你可以尝试实现它。如果您不能将建议转化为代码,那么您就不应该提交已完成的作业。
首先,一旦你对 "d" 进行了位掩码,你需要将它存储回 "begin",这样你就有了一个指针,你可以从中开始读取要转储的字节。
这条指令:
printf( "%08p ", begin );
将以 8 个字符呈现您的 "begin" 地址的十六进制表示,后跟 space。这就是您需要开始内存转储的每一行的方式。
指令:
printf( "%02x ", *(begin++) );
获取 "begin" 指向的字节,并在两个字符中呈现该字节的十六进制表示,后跟 space。然后递增 "begin" 以指向下一个字节。您需要执行此操作 8 或 16 次,具体取决于您希望内存转储的宽度,然后执行 printf( "\n" )
移动到下一行。
然后你需要不断重复上面的操作,直到你的"begin"超过你的"end"。 (因此,您正在查看针对每一行的外循环,以及针对行中每个字节的内循环。)
希望对您有所帮助。
正如@Jean-FrançoisFabre 观察到的,
char c[16]={d};
可能并不像您认为的那样。也就是说,除非您认为它所做的是将存储在 d
中的 long long int
值转换为类型 char
(产生从比 d
本身),用该值初始化数组 c
的第一个元素,并用 0
初始化其他十五个元素。我无法想象您想对结果做什么,但由于您实际上不对它做任何事情,所以这可能没有实际意义。
据我观察,
printf("%x", c);
也可能不会按照您的想法去做。实际上,您不能依赖它来做任何特定的事情,因为它的行为是未定义的。您正在将 指针 作为第二个参数传递给 c
的第一个元素,但是将期望类型为 unsigned int
的值(基于格式) .无论如何,这既 "print[s] the array" 也不会告诉您它 包含什么 。
我怀疑您真正想的是将 c
声明为一个数组,其 地址 -- 而不是内容 -- 是由 [=24 指定的=], 截断为 16 字节对齐的地址。你不能这样做,因为你不能指定你声明的任何变量的地址,但你可以将 c
声明为指针,如下所示:
unsigned char *c = d;
(哦,不,更多指点!)那里有一些实现依赖性,但它可能具有我认为您想要的结果。或者如果你想变得非常聪明,你可以这样做:
unsigned char (*c16)[16] = d;
将c16
声明为指向16unsigned char
数组的指针。它与在您指定的地址处声明数组一样接近。不过,我怀疑您会发现使用其他声明会更容易。
如果你想打印这样一个指针指向的内存的内容("memory dump" 函数似乎不会这样做)那么你需要做更多的工作。标准库的格式化 I/O 函数不直接提供打印数组(出于充分的理由我不会在这里讨论),除了 C 字符串,而且您似乎不想将数据打印为 C 字符串.但是,请考虑此调用,以及如何修改它或使其适应您的目的(假设我上面对 c
的声明):
printf("%02x", *c);
我在大二学习 C class,这个项目是关于处理指针和设计内存转储函数。所以我已经能够努力通过指针并获得要转储的开始和结束地址,甚至对其进行位掩码,我想用开始内存地址初始化一个 char 数组。我用存储屏蔽起始地址的同一个变量初始化它,但是当我打印数组时,它包含一个不同的内存地址。这是函数:
void memDump(void *base, int bytes)
{
unsigned char *begin;
begin = base;//beginning of range of memory
unsigned char *end;// ending range of memory
end = base + bytes;
int a, b;
long long int d=base;
d=d&0xFFFFF0; //trying to bitmask
long long int e=end;
e = e&0xFFFF0; //masked off the beginning and ending range
char c[16]={d}; //loop variables
printf("%x", c);
for (a=begin; a<=end; a+=16)
{
printf("\n%016X\n", d);
printf("%016X\n", a);
printf("%016X", e);
}
}
抱歉,我找不到类似的东西,这是我最后的选择。谢谢!
更新:感谢大家的洞察力,阅读更多关于 C 的内容和一些关于如何调试的文章帮助了我。
你不能 "initialize a char array" 一些 "memory address." 字符数组只能用字符初始化。
Whosebug不是给你做功课的,所以我会给你一些建议,然后你可以尝试实现它。如果您不能将建议转化为代码,那么您就不应该提交已完成的作业。
首先,一旦你对 "d" 进行了位掩码,你需要将它存储回 "begin",这样你就有了一个指针,你可以从中开始读取要转储的字节。
这条指令:
printf( "%08p ", begin );
将以 8 个字符呈现您的 "begin" 地址的十六进制表示,后跟 space。这就是您需要开始内存转储的每一行的方式。
指令:
printf( "%02x ", *(begin++) );
获取 "begin" 指向的字节,并在两个字符中呈现该字节的十六进制表示,后跟 space。然后递增 "begin" 以指向下一个字节。您需要执行此操作 8 或 16 次,具体取决于您希望内存转储的宽度,然后执行 printf( "\n" )
移动到下一行。
然后你需要不断重复上面的操作,直到你的"begin"超过你的"end"。 (因此,您正在查看针对每一行的外循环,以及针对行中每个字节的内循环。)
希望对您有所帮助。
正如@Jean-FrançoisFabre 观察到的,
char c[16]={d};
可能并不像您认为的那样。也就是说,除非您认为它所做的是将存储在 d
中的 long long int
值转换为类型 char
(产生从比 d
本身),用该值初始化数组 c
的第一个元素,并用 0
初始化其他十五个元素。我无法想象您想对结果做什么,但由于您实际上不对它做任何事情,所以这可能没有实际意义。
据我观察,
printf("%x", c);
也可能不会按照您的想法去做。实际上,您不能依赖它来做任何特定的事情,因为它的行为是未定义的。您正在将 指针 作为第二个参数传递给 c
的第一个元素,但是将期望类型为 unsigned int
的值(基于格式) .无论如何,这既 "print[s] the array" 也不会告诉您它 包含什么 。
我怀疑您真正想的是将 c
声明为一个数组,其 地址 -- 而不是内容 -- 是由 [=24 指定的=], 截断为 16 字节对齐的地址。你不能这样做,因为你不能指定你声明的任何变量的地址,但你可以将 c
声明为指针,如下所示:
unsigned char *c = d;
(哦,不,更多指点!)那里有一些实现依赖性,但它可能具有我认为您想要的结果。或者如果你想变得非常聪明,你可以这样做:
unsigned char (*c16)[16] = d;
将c16
声明为指向16unsigned char
数组的指针。它与在您指定的地址处声明数组一样接近。不过,我怀疑您会发现使用其他声明会更容易。
如果你想打印这样一个指针指向的内存的内容("memory dump" 函数似乎不会这样做)那么你需要做更多的工作。标准库的格式化 I/O 函数不直接提供打印数组(出于充分的理由我不会在这里讨论),除了 C 字符串,而且您似乎不想将数据打印为 C 字符串.但是,请考虑此调用,以及如何修改它或使其适应您的目的(假设我上面对 c
的声明):
printf("%02x", *c);