提问人:Sir Muffington 提问时间:3/13/2023 更新时间:3/13/2023 访问量:41
在 C 语言中实现原始哈希函数时的 Segfault
Segfault while implementing a primitive hashing function in C
问:
我正在尝试集成一个相当原始的“哈希”函数。我知道它不是加密安全的,它只是为了学习......
它可以编译,但每次都会出现段错误......
我把第一个参数作为输入。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
unsigned int hash_pw(const char* p) {
unsigned int i;
unsigned int res = 0;
for(i = 50; i > 45; i--) {
res += p[i] * (50 - i);
}
return res;
}
int main (int argc, const char* argv[])
{
int asd = (int) malloc(50*sizeof(int));
asd = (unsigned int) hash_pw(argv[1]);
printf("%s\n", asd);
free(asd);
return 0;
}
答:
2赞
0___________
3/13/2023
#1
主要问题:
1.
int asd = (int) malloc(50*sizeof(int));
asd = (unsigned int) hash_pw(argv[1]);
printf("%s\n", asd);
free(asd);
asd
是一个整数。您尝试将其用作“printf”函数中的指针。调用 malloc 完全没有意义,因为您将指针分配给 .调用免费也无效int
for(i = 50;
您的字符串可能不是 51+ 字符长,并且可能会调用未定义的行为
阅读警告,不要让它们静音
<source>: In function 'main':
<source>:21:11: warning: initialization of 'int' from 'void *' makes integer from pointer without a cast [-Wint-conversion]
21 | int asd = malloc(50*sizeof(int));
| ^~~~~~
<source>:23:10: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'int' [-Wformat=]
23 | printf("%s\n", asd);
| ~^ ~~~
| | |
| | int
| char *
| %d
<source>:24:6: warning: passing argument 1 of 'free' makes pointer from integer without a cast [-Wint-conversion]
24 | free(asd);
| ^~~
| |
| int
In file included from <source>:5:
/opt/compiler-explorer/arm/gcc-arm-none-eabi-11.2-2022.02/arm-none-eabi/include/stdlib.h:94:15: note: expected 'void *' but argument is of type 'int'
94 | void free (void *) _NOTHROW;
| ^~~~~~
<source>:19:15: warning: unused parameter 'argc' [-Wunused-parameter]
19 | int main (int argc, const char* argv[])
| ~~~~^~~~
0赞
RATriches
3/13/2023
#2
此代码存在一些错误(我没有考虑其逻辑)。
- malloc 函数返回一个指针,在本例中为“int*”。
- 为了返回填充向量(通过哈希函数),我通常会放置一个指针参数,在这种情况下,我可能会执行此“int hash_pw(int **asd, const char *p)”。然后函数调用可以是:
int *asd = (int*) malloc(50*sizeof(int));
int ret = hash_pw(&asd, argv[1);
注意:您需要注意“for”限制,在代码中,for 以“i=50”开头,但“asd”向量只能在 0-49 之间建立索引。我可能会像这样执行“has_pw”功能
int hash_pw(int **asd, int max, const char* p) {
for (int i = max -1 ; ....
asd[i] = ....
}
但是,如果你想在原始逻辑中返回一个“哈希和”,你可以做这样的事情:
unsigned int hash_pw(unsigned int max, const char* p) {
unsigned int i;
unsigned int res = 0;
for(i = max-1; i > 45; i--) {
res += p[i] * (max - i);
}
return res;
}
int main (int argc, const char* argv[])
{
unsigned int asd;
asd = hash_pw(50, argv[1]); // note: the max arg would be argc, or not?
printf("%d\n", asd);
return 0;
}
评论
i = 50; p[i];
对于具有 50 个元素的数组,是立即越界访问。编辑:实际上,甚至不是 50 个元素数组。它是一个 CLI 参数。是什么让您确定至少有 51 个字符?p
argv[1]