我有一个随机的自然数,并打印出从最后一个数字到输入的collatz猜想。 collatz猜想的步骤是: (a)从任何正整数N开始。 (b)如果N是奇数,则将其乘以3并加1.(即N←3N + 1) (c)如果N是偶数,则除以2.(即N←N / 2) (d)重复。 并且它总是以4 - > 2-> 1-> 4-> 2-> 1结束...... 我的电脑告诉我(projectname).exe在输入整数后停止工作。
最重要的一点可能是我们应该为猜想分配空间,如果完全使用它就加倍。
我的代码是:
int main()
{
unsigned long int input =0;
int max =16;
long int *collatz;
collatz = malloc(max*sizeof(long int));
long int *n = NULL;
long int *u = NULL;
int counter=0;
printf("Please enter a natural number:");
scanf("%lu", input);
printf("%lu\n",input);
if (input <1)
{
printf ("ERROR, not a natural number");
return 1;
}
n = collatz;
*n = input;
while (*n!=1)
{
if (counter == max)
{
max = max*2;
collatz = realloc (collatz,max*sizeof(long int));
}
if ((*n)%2 == 1)
{
*n=(3*(*n))+1;
}
else if ((*n)%2 == 0)
{
*n=(*n)/2;
}
*u=*n;
n=n+1;
*n=*u;
counter++;
int *i =0;
for (i=n;*i!=input;i--)
{
printf("%lu\t",*i);
}
}
return 0;
}
我想我的realloc错了,其他大部分东西对我来说都没有什么大错(这并不意味着没有错误,可能是错误的)。
感谢您的帮助!
答案 0 :(得分:0)
故障发生在scanf()
。
$ echo 4 | ./a.out
ASAN:DEADLYSIGNAL
=================================================================
==3684==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f37ae1007fe bp 0x7fffb3148b60 sp 0x7fffb3148480 T0)
==3684==The signal is caused by a WRITE memory access.
==3684==Hint: address points to the zero page.
#0 0x7f37ae1007fd in _IO_vfscanf (/lib/x86_64-linux-gnu/libc.so.6+0x5c7fd)
#1 0x7f37ae10f72f in __isoc99_vscanf (/lib/x86_64-linux-gnu/libc.so.6+0x6b72f)
#2 0x433206 in __interceptor___isoc99_vscanf /home/development/llvm/3.9.0/final/llvm.src/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1187:1
#3 0x433206 in __interceptor___isoc99_scanf /home/development/llvm/3.9.0/final/llvm.src/projects/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:1208
#4 0x4e4954 in main /home/brian/tmp/collatz/coll.c:15:5
#5 0x7f37ae0c482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
#6 0x418dc8 in _start (/home/brian/tmp/collatz/a.out+0x418dc8)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/lib/x86_64-linux-gnu/libc.so.6+0x5c7fd) in _IO_vfscanf
==3684==ABORTING
此外,我在尝试编译时收到警告,看起来他们可以帮助识别问题:
$ clang -fsanitize=address -g coll.c
coll.c:15:18: warning: format specifies type 'unsigned long *' but the argument has type 'unsigned long' [-Wformat]
scanf("%lu", input);
~~~ ^~~~~
coll.c:47:15: warning: incompatible pointer types assigning to 'int *' from 'long *' [-Wincompatible-pointer-types]
for (i=n;*i!=input;i--)
^~
coll.c:49:28: warning: format specifies type 'unsigned long' but the argument has type 'int' [-Wformat]
printf("%lu\t",*i);
~~~ ^~
%d
3 warnings generated.
修复scanf()
后,我仍然可以看到*u=*n
行发生运行时故障。您应该启动调试器以查看此问题。