Sizeof and Strlen

Sizeof and Strlen

本文关键字:Strlen and Sizeof      更新时间:2023-10-16

我正在尝试使用Salt和密码实现加密。由于Salt的推荐大小是64位,所以我声明。

char Salt[8];

我使用RAND_pseudo_bytes来获得一个随机的Salt:

RAND_pseudo_bytes((unsigned char*)Salt, sizeof Salt);

并且因为每次编译时hexdump输出的长度不同(有时是5,大多数是24字节),因为我错误地使用strlen代替sizeof:

RAND_pseudo_bytes((unsigned char*)Salt, strlen(Salt));

我试着用下面这行来弄清楚发生了什么:

printf("n%dn",strlen(Salt));

每次输出24。

所以,我的问题是:为什么strlen(Salt)=24当我声明Salt的长度为8(sizeof(Salt)=8)?我可以理解9(带"",尽管我不完全确定这到底是怎么回事),但24让我觉得很奇怪。谢谢你。

strlen将沿着您给它的指针向下走,并计算字节数,直到它达到空字节。在这种情况下,8字节的字符数组没有空字节,因此strlen愉快地继续越过边界进入堆栈上定义的字符数组以外的内存区域,无论发生什么都将决定strlen的行为。在本例中,在数组开始后24字节处,有一个空字节

  1. 不要使用char来表示字节。
  2. 一个字节超过一半的值是不可打印的,即它们没有相应的可打印值。
  3. 我建议您使用printf("0x%02Xn", array[i]);
  4. 迭代uint8_t数组

strlen()搜索第一个空字符并计算除该空字节外的所有字节数。一个salt是8个非零字节-并且不能保证下一个字符是空字节。

sizeof是返回存储特定数据结构所需的字节数的操作符。当应用于字符数组时,它表示数组名称不会衰减到指向其第一个元素的指针的三种情况(另外两种情况是使用&并通过字符串字面量进行初始化)。

strlen是一个函数,假设它的输入是一个以null结尾的字符序列。因为当您将字符数组的名称传递给函数时,它确实衰减到其第一个元素的指针,因此strlen无法知道原始数据结构的大小(像sizeof一样)。它得到的只是一个指向char的指针。它确定字符串结束的唯一方法是遍历字符序列,寻找''。在您的示例中,它无法在内存中的第24个字节之前找到一个。那纯属偶然。

尝试用:

初始化数组
char Salt[8] = {0};

并确保您的RAND_pseudo_bytes函数保留处理字符串中的哨兵''。

除了salt的null终止,正如其他人指出的那样,您需要将printf中的格式说明符更改为%zu,因为strlen的返回类型是size_t。使用错误的说明符会调用未定义行为

关于strlen()的问题

strlen()正在计算的是内存中到第一个''的字节数。

char Salt[9] = { '' };

用所有的'' s初始化Salt


注意:正如@OliCharlesworth指出的,Salt可以嵌入null。不要使用任何str*()方法。您只需要使用mem*()方法并自己跟踪长度。不要依赖sizeof,因为数组在传递给函数时会转换为指针。