为何crypt()函数不接受合法两位nonce?技术排查求助
问题分析与解决方案
你的问题核心是悬挂指针导致的未定义行为,这也是crypt()函数表现异常的根本原因。咱们一步步拆解:
1. 核心问题:concatenateCharacters()返回了无效指针
看你的concatenateCharacters函数:
string concatenateCharacters(char characters[], int arraySize) { char terminator[1] = {'\0'}; char bigEnoughArray[arraySize + 1]; // 局部栈数组 for (int i = 0; i < arraySize; i++) { bigEnoughArray[i] = characters[i]; } return strcat(bigEnoughArray, terminator); }
bigEnoughArray是函数内部的局部栈内存数组,当函数执行完毕返回时,这个数组所在的栈帧会被销毁,内存会被操作系统回收或后续函数调用覆盖。你返回的是这个数组的地址(strcat返回目标数组的指针),这就成了悬挂指针——指向已经无效的内存区域。
这种情况下,后续使用nonce指针的行为都是未定义的:有时候内存内容还没被覆盖,看似能工作;有时候内存被其他操作(比如第一个crypt()调用)覆盖,就会出现crypt()返回null的情况。
2. 两种输出异常的原因
- 第一种情况(两个
crypt()都调用):第一个crypt("myPassword", "14")的函数调用会使用栈内存,直接覆盖了bigEnoughArray原来的内容,导致nonce指向的内存不再是"14",crypt()拿到无效的salt,返回null。 - 第二种情况(只调用第二个
crypt()):此时bigEnoughArray的内存还没被覆盖,nonce暂时能读到"14",但这只是巧合。crypt()返回的哈希缺少前两位,也是未定义行为的表现——因为内存随时可能被其他操作篡改,结果完全不可靠。
另外还要注意:你定义的nonceAsArray[2]是长度为2的字符数组,没有存储字符串终止符'\0',本质上它不是一个合法的C风格字符串,这也会给后续处理埋下隐患。
3. 修复方案
方案一:用动态内存分配避免悬挂指针
修改concatenateCharacters函数,使用malloc分配堆内存,这样内存不会随函数结束销毁:
string concatenateCharacters(char characters[], int arraySize) { // 分配足够的内存存储字符 + 终止符 char *bigEnoughArray = malloc(arraySize + 1); if (bigEnoughArray == NULL) { // 内存分配失败,返回NULL或处理错误 return NULL; } // 复制字符到新内存 for (int i = 0; i < arraySize; i++) { bigEnoughArray[i] = characters[i]; } // 手动添加字符串终止符 bigEnoughArray[arraySize] = '\0'; return bigEnoughArray; }
注意:使用完nonce后,一定要用free(nonce)释放内存,避免内存泄漏。
方案二:直接在主函数中生成salt字符串
其实没必要单独写拼接函数,直接在主逻辑里处理更简洁:
string hash = "14dJperBYV6zU"; // 分配3字节内存:2个salt字符 + 1个终止符 char *nonce = malloc(3); if (nonce == NULL) { // 处理内存分配失败的情况,比如退出程序 return 1; } // 提取前两位字符 nonce[0] = hash[0]; nonce[1] = hash[1]; // 添加字符串终止符,确保是合法的C字符串 nonce[2] = '\0'; // 调用crypt printf("first hash: %s\n", crypt("myPassword", "14")); printf("second hash: %s\n", crypt("myPassword", nonce)); // 释放内存 free(nonce);
4. 后续排查方向
遇到这类时好时坏的异常,优先排查:
- 指针是否指向已释放的局部内存(悬挂指针)
- 传递给函数的字符串是否是合法的C风格字符串(必须以
'\0'结尾) - 内存生命周期问题:局部变量的内存只在函数执行期间有效,不要返回局部变量的地址
内容的提问来源于stack exchange,提问作者he1zn0erg
相关产品推荐
相关产品推荐

