2017-01-18 6 views
0

У меня есть желание взять одно случайное натуральное число и распечатать гипотезу 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 перестает работать после ввода целого числа.realloc, динамическое распределение памяти

Наиболее важным моментом является то, что мы должны выделить пространство для гипотезы и удвоить его, если оно используется полностью.

Мой код:

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; 
} 

Я предполагаю, что я получил перераспределить так, большинство других вещей не большая мистерия для меня (это не означает, что нет никаких ошибок, thereprobably являются).

Благодарим за помощь!

+0

Никогда не делайте 'x = realloc (x, ...);' – 0andriy

+0

почему? Нам было предложено использовать его ... @ 0andriy –

+0

Просто подумайте об этом. Это легко исправить. Ваш код содержит серьезную ошибку прямо сейчас. – 0andriy

ответ

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 линии , Чтобы увидеть эту проблему, вы должны запустить отладчик.

+0

большое спасибо! –