realloc,动态内存分配

时间:2017-01-18 18:41:27

标签: c realloc

我有一个随机的自然数,并打印出从最后一个数字到输入的collat​​z猜想。 collat​​z猜想的步骤是: (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错了,其他大部分东西对我来说都没有什么大错(这并不意味着没有错误,可能是错误的)。

感谢您的帮助!

1 个答案:

答案 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行发生运行时故障。您应该启动调试器以查看此问题。