gpt4 book ai didi

c++ - 将类指针转换为字符指针(不安全)

转载 作者:行者123 更新时间:2023-11-30 05:36:29 24 4
gpt4 key购买 nike

我正在制作一种编程语言。我以前做过几次,但这次我想做得更好,在开发时使用更多的技术。其中之一是我使用了 2 个定义的预处理器,_DEBUG (由我制作,我使用 _ 所以它不会与 Visual Studio 已经定义的 DEBUG 混淆)和 _DEBUG_VARS .当我有 _DEBUG = 1 ,我想做一些调试,做的时候 _DEBUG_VARS = 1 ,我想做 Var 转储等。其中之一是十六进制转储。我敢打赌标准库中已经有一个,但我想要我自己的。我希望它工作的方式是传递一个指向任何类的指针(我使用模板 <class T_HEX> 使其工作。然后它会将我输入的 T_HEX* 转换为 char*,然后获取T_HEX 的大小,从 char* 开始遍历所有字节(记住 char* 是 RAM 中字符所在的位置)。然后我将用 2 个十六进制数写出该字节。我知道这真的很不安全,我编写代码的方式是,当我执行 _DEBUG_VARS = 1 时,它会创建这些函数,而当我执行 _DEBUG_VARS = 0 时,这些函数将替换为空定义,以防万一使用,将在期间替换为空定义编译时。因为它不安全,我只会在开发过程中使用它。发布版本不会有这个。

所以,对于代码。为了尝试这个,我创建了一个名为 Test 的类:

class Test
{
public:
char* Allapoto = "AAaaAAaA\0";
int Banana = 1025;
bool Apple = true;
};

注意我这里没有函数,这是因为我希望在使 HexDump 工作时能够简单一些。然后 HexDump 自行运行:

int DEBUG_HexLineCounter = 0;
#define H_D_CUT 10
#define H_D_L() (DEBUG_HexLineCounter % H_D_CUT > 0)
#define H_D_NL() ((++DEBUG_HexLineCounter % H_D_CUT) == 0)

template <class T_HEX>
void HexDump(T_HEX* var)
{
char* ptr = reinterpret_cast<char*>(var);
char* off_ptr = NULL;

int size = sizeof(*var);
for (int i = 0; i < size; i++)
{
off_ptr = (ptr + i);
char c = *off_ptr;

HexDump(&c);
}
if (H_D_L())
std::cout << std::endl;
}

void HexDump(char* c)
{
char _char = *c;
char ch = _char / 0x10;
char cl = _char % 0x10;

std::cout << std::hex << static_cast<int>(ch) << std::hex << static_cast<int>(cl) << " ";
if (H_D_NL())
std::cout << std::endl;
}

我省略了 _DEBUG 和 _DEBUG_VARS 部分,因为我知道它们有效,所以它们在这里并不重要。我运行它,我想从整个类的值中获取以字节为单位的十六进制值。我使用以下代码在程序的主要功能(这是一个 Win32 控制台应用程序)中运行它:

Test test;
HexDump<Test>(&test);

这导致了输出:

18 5e 17 01 01 04 00 00 01 00

对我来说,这并没有我想要的那么清楚。所以我添加了这段代码:

HexDump<char>(test.Allapoto);
HexDump<int>(&test.Banana);
HexDump<bool>(&test.Apple);

所以它现在看起来像这样:

Test test;
HexDump<Test>(&test);
HexDump<char>(test.Allapoto);
HexDump<int>(&test.Banana);
HexDump<bool>(&test.Apple);

我确实运行了这个,这次我得到了更多有趣的东西:

18 5e 17 01 01 04 00 00 01 00
00 00
41
01 04 00 00
01

所以在这之后,我想,嗯,一些熟悉的数字,一些我以前见过的。第一件事 01 04 00 00 和 01,我之前在更大的(第一次测试)中见过它们。如果我查看类结构,我发现我在最后放了一个 bool,在它之前放了一个 int。所以 01 一定是我的 bool,因为 bool 是 1 个字节,它也被设置为 true,然后在此之前,我声明了一个 int。一个 int 是 32 位或 4 个字节,在这里我看到 01 04 00 00。然后我们有 char,它在 int 之前。我总是完成变量并传递一个指向它的指针。现在我想做一个字符,并传入一个字符指针。在这种情况下,第一个字符是“A”。我们看控制台输出,可以看到显示的是41,你可能会问为什么是41?好吧,它是十六进制的,十六进制的 41 是十进制的 65,这是 A 的 ascii 值。

但现在回答我的问题。

  1. 如果我们查看 char 值之前的那个:00 00。为什么第一个输出中没有这些?

  2. 如果我们查看第一个输出,并想到问题 1,为什么字符没有写在那里,在本例中是 41?

  3. 现在 41 不在那里,我们还可以看到 char*(字符串)的其余部分也不在那里。也许那些 18 5e 17 01 是指向 char* 字符串的指针,对吗?

  4. 有没有其他的方法来做十六进制哑?我既想要自定义代码,也想要标准库中的函数(如果有的话)。

谢谢

最佳答案

似乎把事情搞砸的是对 HexDump 的一次调用可能会导致多行。如果您将逻辑更改为在通用 HexDump 末尾始终输出换行符从来没有在专业HexDump每次调用 HexDump 都会收到一条线.

这可能会解决您的一些问题。

没有这些修改我得到输出:

--- &test:
6f 10 40 00 00 00 00 00 01 04
00 00 01 00 00 00
--- test.Allapoto:
41
--- &test.Banana:
01 04 00
00
--- &test.Apple:
01

通过修改换行符处理,我得到:

--- &test:
6f 10 40 00 00 00 00 00 01 04 00 00 01 00 00 00
--- test.Allapoto:
41
--- &test.Banana:
01 04 00 00
--- &test.Apple:
01
  1. If we look at the one before the char value: 00 00. Why isn't those in the first output?

00 00 是第一行的一部分,这里一切正常。

  1. If we look in the first output, and think of question 1, why isn't the char written there, in this case 41?

41 是该行的第一个字符,而在您存储指针的结构中。

  1. Now that it isn't 41 there, we can also see that the rest of the char* (string) isn't there either. Maybe those 18 5e 17 01 is a pointer to the char* string, am I right?

是的,你是对的。

  1. Is there another way to do a hex dumb? I want both custom code, and maybe if there is, a function in the standard library.

您必须意识到,执行十六进制转储的任何方式都将跨越标准中定义的边界。您将不得不依赖一些实现定义的行为,并且在某种程度上,未定义的行为不会导致鼻恶魔。大多数编译器可能会在此处正常运行以允许十六进制转储。

您可以做一些改进。首先你应该使用 unsigned char而不是 char为了保证在将字节转换为十六进制时不会得到符号扩展。

其次,您应该改进换行逻辑。您可能应该将其限制为通用 HexDump函数并使计数器成为局部变量。例如:

template <class T_HEX>
void HexDump(T_HEX* var)
{
unsigned char* ptr = reinterpret_cast<unsigned char*>(var);
unsigned char* off_ptr = NULL;

int size = sizeof(*var);
for (int i = 0; i < size; i++)
{
off_ptr = (ptr + i);
unsigned char c = *off_ptr;

if( i && i%8 == 0 )
std::cout << std::endl;
HexDump(&c);
}
std::cout << std::endl;
}

void HexDump(unsigned char* c)
{
unsigned char _char = *c;
unsigned char ch = _char / 0x10;
unsigned char cl = _char % 0x10;

std::cout << std::hex << static_cast<int>(ch) << std::hex << static_cast<int>(cl) << " ";
}

关于c++ - 将类指针转换为字符指针(不安全),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33544193/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com