小端序,将两个char*内存的数据写入一个uint16内存里,四个char*写入一个int32----字符串

本文探讨了如何将两个char类型的ASCII码通过uint16类型进行存储,并展示了如何将int的值进行前后对调。通过实例演示了字符到二进制转换和整数位操作技巧。

一个char类型占一个字节的地址,一个int占4个字节,一个uint16占2个字节的地址

将两个char分别存入一个uint16类型的高八位地址和低八位地址,会把char转化为对应的ASCII码对应的二进制数字,然后将二进制存入unint16里面。

char* arr="1A" ;
uint16_t trans = (arr[0] << 8) + arr[1]; 

arr[0]: 1对应的ASCII码:49=00110001
arr[1]: A对应的ASCII码:65=01000001

转换过后trans的值为12609(DEC十进制)= 00110001 01000001

如果要把一个int的值前后整体对调存入另一个int

int int_32_ = idx[3] <<24 | (idx[2] << 16) | idx[1] << 8 | idx[0];
idx += sizeof(int_32_);
这是一个非常关键的问题,涉及到 **指针类型、内存写入、越界访问****内存布局**。我们来一步一步分析: --- ## ✅ 你提到的背景: - `char *pCategoryList` 是一个指针,指向通过 `malloc(5)` 分配的内存- 你之前已经写入一个字节:`*pCategoryList = 0x02`,这一步是安全的。 - 然后你又执行了:`*pCategoryList = (uint8_t)b`,其中 `b` 是 `int8_t` 类型,值为 `-1`(即 `0xFF`)。 - 你发现程序崩溃,或者 `pCategoryList` 后面的 `malloc` 内存块(如 `pRevisionList`)的元数据被破坏了。 --- ## ✅ 问题核心: 你可能以为你只写入一个字节,但**实际上你可能写入了 4 个字节**,导致了 **越界写入****数据破坏**--- ## ✅ 详细解释: ### 1. `char *pCategoryList` 类型 - `char *` 是一个指向 `char` 的指针,在 C 中 `char` 是 1 字节。 - 所以你确实可以安全地写入一个字节: ```c *pCategoryList = 0x02; // ✅ 正确写入一个字节 ``` --- ### 2. 你以为写入一个字节,实际上写入了 4 个字节? 你可能写了这样的代码: ```c int8_t b = -1; *pCategoryList = b; // 你以为只写入一个字节? ``` 但实际上,你可能写了: ```c *(int *)pCategoryList = b; // ❌ 错误方式:强制换为 int*写入 4 字节 ``` 或者你使用了 `sprintf`、`memcpy`、或某些库函数,导致你写入的是 `int` 类型: ```c int temp = b; *pCategoryList = temp; // ❌ 错误:char = int,会写入 int 的最低一个字节 ``` 或者你写成: ```c *((int *)pCategoryList) = b; // ❌ 错误:写入 4 字节到只分配了 5 字节的内存 ``` --- ## ✅ 示例说明: ```c char *pCategoryList = malloc(5); // 分配 5 字节 pCategoryList[0] = 0x02; // ✅ 写入一个字节 int8_t b = -1; // 错误写法:强制换为 int 指针,写入 4 字节 *((int *)pCategoryList) = b; // ❌ 写入 4 字节到只分配了 5 字节的内存 ``` ### 内存写入情况: | 地址偏移 | 内容(十六进制) | |----------|------------------| | +0 | FF | | +1 | FF | | +2 | FF | | +3 | FF | 你只分配了 5 字节,但写入了 4 字节,从偏移 `+0` 到 `+3`,是合法的。 但如果你写入的是: ```c *((int *)(pCategoryList + 1)) = b; // ❌ 写入地址从 +1 开始,写入 4 字节 ``` 则会写入偏移 `+1 ~ +4`,覆盖了你分配的最后一个字节(+4),也属于越界写入--- ## ✅ 为什么会导致 `pRevisionList` 的元数据破坏? 假设你紧接着分配了另一个内存块: ```c char *pRevisionList = malloc(10); ``` `malloc` 会在 `pCategoryList` 后面放置元数据(如块大小、指针等),然后才是 `pRevisionList` 的可用空间。 如果你越界写入 `pCategoryList` 的内存: ```c *((int *)(pCategoryList + 1)) = -1; // 写入偏移 +1 ~ +4 ``` 那么你就可能覆盖了 `pRevisionList` 的元数据,比如它的: - 块大小(size) - 指向前一个/后一个块的指针(用于链表管理) 这就导致: - `free(pRevisionList)` 时崩溃 - 内存泄漏 - 程序行为异常 --- ## ✅ 为什么 `b == 0` 时不会出问题? 当 `b == 0` 时,整型提升后是 `0x00000000`,如果你错误地写入 4 字节: ```c *((int *)pCategoryList) = 0; // 写入四个 00 ``` 虽然也越界,但写入的是 `00 00 00 00`,不会破坏 `malloc` 的元数据结构(如 size 字段为 0 可能不会触发错误逻辑),所以程序“看起来”没问题。 但这仍然是 **未定义行为(UB)**,只是暂时没出事。 --- ## ✅ 正确写法(避免越界) ### ✅ 方法一:确保写入的是一个字节 ```c pCategoryList[0] = (uint8_t)b; // ✅ 安全写入一个字节 ``` ### ✅ 方法二:使用 `memcpy` ```c memcpy(pCategoryList, &b, sizeof(b)); // ✅ 明确复制一个字节 ``` ### ✅ 方法三:避免强制类型写入 不要写成: ```c *(int *)pCategoryList = b; // ❌ 错误写法 ``` --- ## ✅ 总结 | 写入方式 | 写入字节数 | 是否越界 | 是否破坏元数据 | |----------|------------|----------|----------------| | `pCategoryList[0] = b;` | 1 字节 | ❌ | ❌ | | `*(int *)pCategoryList = b;` | 4 字节 | ✅ | ✅ | | `memcpy(pCategoryList, &b, 1);` | 1 字节 | ❌ | ❌ | | `*(int *)(pCategoryList + 1) = b;` | 4 字节 | ✅ | ✅ | --- ## ✅ 关键点回顾 - `char *` 指针只能安全地写入 1 字节 - 强制类型换为 `int *` 并写入会导致写入 4 字节,可能越界 - `malloc` 分配的内存前后有元数据,越界写入会破坏它 -写入值为 `0` 时,虽然仍越界,但不会破坏关键数据,所以暂时“没出事” ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值