C语言如何读取函数参数中的字符串?哈希键函数实现疑问
解决C语言哈希键函数中的字符串越界与参数初始化问题
嘿,我来帮你理清楚这个问题——你写的哈希函数里有几个C语言语法和内存安全的坑,咱们一步步拆解解决:
你的代码里的核心问题
- 函数参数默认初始化不合法:C语言根本不支持给函数参数设默认值,
int hashKey(char *c = calloc(100, sizeof(char))这种写法编译器直接会报错,参数的内存分配逻辑绝对不能放在参数列表里。 - 字符串长度计算的冗余:你手动用while循环数字符串长度完全没必要,C标准库的
strlen()函数就是干这个的,既高效又能保证不会因为漏判导致越界。 - 潜在的越界风险:如果传入的字符串没正确以
'\0'结尾,你的while循环会一直读内存直到碰到0,这妥妥会触发越界访问,搞不好直接崩溃。
正确的实现思路
1. 先搞定用户输入的安全读取
要避免越界,首先得在调用哈希函数之前就把用户输入的字符串安全读进来。别在哈希函数里分配内存(不然调用者很容易忘记释放,造成内存泄漏),单独写个安全读取的函数:
#include <stdio.h> #include <stdlib.h> #include <string.h> // 安全读取用户输入的字符串,最多读max_len个字符 char* safe_read_string(size_t max_len) { // 多分配一个字节存结束符'\0' char* buffer = malloc(max_len + 1); if (!buffer) { perror("内存分配失败"); return NULL; } // 用fgets读取,自动限制长度,避免缓冲区溢出 if (fgets(buffer, max_len + 1, stdin) == NULL) { free(buffer); return NULL; } // 去掉fgets可能读进来的换行符 buffer[strcspn(buffer, "\n")] = '\0'; return buffer; }
2. 修正哈希键函数
哈希函数只需要接收一个合法的、以'\0'结尾的字符串指针就行,不用搞复杂的参数初始化:
// 传入const char*表示我们不会修改这个字符串,更安全 int hashKey(const char *c) { // 先判断空指针,避免程序崩溃 if (c == NULL) { return -1; // 返回特殊值表示输入错误 } int h = 0; size_t len = strlen(c); // 直接用strlen拿到有效字符串长度 // 用数组下标访问比指针偏移更直观易读 for (size_t k = 0; k < len; k++) { h += c[k]; } return h % 10; // 取模得到0-9的哈希值 }
3. 完整调用示例
把输入和哈希计算结合起来,整体逻辑就通顺了:
int main() { printf("请输入字符串:"); // 最多读99个字符,加上结束符总共100字节 char* input = safe_read_string(99); if (!input) { return 1; } int hash = hashKey(input); printf("计算得到的哈希键值:%d\n", hash); free(input); // 记得释放之前malloc的内存,别漏了! return 0; }
额外小提示
如果因为特殊需求,你必须在哈希函数内部处理内存分配(还是不推荐,因为调用者很容易忘释放),可以用二级指针来返回分配的内存:
int hashKey(char **c) { *c = calloc(100, sizeof(char)); if (!*c) { perror("内存分配失败"); return -1; } printf("请输入字符串:"); fgets(*c, 100, stdin); (*c)[strcspn(*c, "\n")] = '\0'; int h = 0; size_t len = strlen(*c); for (size_t k = 0; k < len; k++) { h += (*c)[k]; } return h % 10; } // 调用的时候要这么写: // char* input; // int hash = hashKey(&input); // free(input); // 一定要记得释放!
另外,你现在的哈希逻辑是简单求和取模,对于简单需求完全够用;如果要更均匀的哈希结果,可以试试加入乘法或者移位操作,不过这都是后话啦。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

