我正在编写一个计算信息熵的程序,这是熵(H)的函数
这里使用base 2 log
然后这是我的程序
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <signal.h>
typedef struct vars {
char *var;
float prob;
} CHOISES;
float infocont(float x);
float entropy(CHOISES *, int);
void onsig(int);
int main(int argc, char *argv[])
{
int i = 0;
int siz = 0;
float H = 0.0;
printf("input the number of vars: ");
scanf("%d", &siz);
//printf("echo: %d\n", siz);
CHOISES chs[siz];
signal(SIGSEGV, onsig);
for (i = 0; i < siz; i++) {
printf("%d: ", i + 1);
scanf("%s %f", chs[i].var, &chs[i].prob); /* HERE IS THE ERROR */
//printf("echo: %s %f\n", chs[i].var, chs[i].prob);
}
H = entropy(chs, siz);
printf("Entropy is %f\n", H);
}
void onsig(int signo)
{
fprintf(stderr, "signal caught: %d\nSEGMENTATION FAULT\n", signo);
}
float infocont(float x)
{
return (log(1/x) / log(2));
}
float entropy(CHOISES chs[], int len)
{
short i;
float entropy;
for (i = 0; i < len; i++) {
entropy += chs[i].prob * infocont(chs[i].prob);
}
return entropy;
}
我的问题是当我输入第一个输入并点击输入时会产生分段错误。 我使用了调试器,我发现为结构分配数据会导致分段错误。 这是执行此代码行的时间
scanf("%s %f", chs[i].var, &chs[i].prob);
发生了分段错误。
但我在这段代码中无法想到错误。
为什么scanf()会出现分段错误?
答案 0 :(得分:6)
chs[i].var
是一个悬空指针。你必须首先malloc
记忆。
chs[i].var = malloc(Max_str_len + 1); //<--- this
scanf("%s %f", chs[i].var, &chs[i].prob);
答案 1 :(得分:1)
for (i = 0; i < 10; i++)
{
printf("%d: ", i + 1);
scanf("%s %f", chs[i].var, &chs[i].prob); /* HERE IS THE ERROR */
//printf("echo: %s %f\n", chs[i].var, chs[i].prob);
}
是的,这段代码确实引入了错误。
如果siz < 10
怎么办?然后,这将导致另一个Segfault
。
您应该使用for (i = 0; i < siz; i++)
代替for (i = 0; i < 10; i++)
chs[i].var
没有指向任何有效的内存位置,因为它只包含垃圾,然后scanf()
尝试将字符串存储在该内存位置,导致{{1} }
您应首先使用SegFault
,malloc
等分配内存。
将内存分配给calloc
后,请勿忘记在chs[i].var
之前检查它是否与NULL
不相等,因为这可能会导致scanf()
{1}}。
所以工作解决方案将是
SegFault