Используя функцию malloc (), чтобы установить глобальный размер массива, получить дамп ядра - PullRequest
0 голосов
/ 24 декабря 2018

У меня есть глобальная переменная массива с именем int *PRIME_ARRAY.Затем в моей функции main я спрашиваю пользователя длину этого массива, сохраняю его в int quantita и устанавливаю его с PRIME_ARRAY = malloc(sizeof(int) * quantita).

Когда я не компилирую ошибки, но когда я выполняю его и вставляю число, например «7», это вызывает ошибку дампа ядра.Я пытаюсь отладить его «путем новичка», помещая фразы printf() среди всего кода.Таким образом, кажется, что проблема заключается в использовании функции malloc().

(я должен иметь массив в качестве глобальной переменной. next_prime() должен иметь только int last в качестве аргумента)

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int next_prime(int last);

int *PRIME_ARRAY;

int main(void)
{
  int quantita;

  printf("Quanti numeri primi vuoi stampare ? ");
  scanf("%i", &quantita);

  PRIME_ARRAY = malloc(sizeof(int) * quantita);

  int last = 2;

  for (int i = 0; i < quantita; i++){
    PRIME_ARRAY[i] = last;
    last = next_prime(last);
  }

  free(PRIME_ARRAY);
  return 0;
}

int next_prime(int last)
{
  printf("%i ", last);

  bool isPrime = false;

  do {
    last++;

    for (int i = 0; i < sizeof(PRIME_ARRAY)/sizeof(int); i++){    
      if (last % PRIME_ARRAY[i] != 0) isPrime = true; break;    
    }    
  } while (!isPrime);

  return last;    
}

Ответы [ 3 ]

0 голосов
/ 24 декабря 2018

Как сказали в комментариях Перетт Барелла и Юрий Дж., Ошибка в том, что sizeof(PRIME_ARRAY) в этом случае возвращает размер указателя.sizeof(array) отлично работает только тогда, когда массив объявлен как массив, то есть со статической длиной.(Как int array[7] или int array[] = {1, 2, 3})

Чтобы исправить код, я просто добавил вызов глобальной переменной int array_lenght, заменив scanf("%i", &quantita); на scanf("%i", &array_length); и i < sizeof(PRIME_ARRAY)/sizeof(int) на i < array_lenght.

#include<stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int next_prime(int last);

int *PRIME_ARRAY, array_lenght;

int main(void){

  printf("Quanti numeri primi vuoi stampare ? ");

  scanf("%i", &array_lenght);

  PRIME_ARRAY = malloc(sizeof(int) * array_lenght);

  int last = 2;

  for (int i = 0; i < array_lenght; i++){

    PRIME_ARRAY[i] = last;

    last = next_prime(last);

  }

  free(PRIME_ARRAY);

  printf("\n");

  return 0;

}

int next_prime(int last){

  printf("%i ", last);

  bool isPrime = false;

  do {

    last++;

    for (int i = 0; i < array_lenght; i++){

      if (last % PRIME_ARRAY[i] != 0) isPrime = true; break;

    }

  } while (!isPrime);

  return last;

}
0 голосов
/ 27 декабря 2018

Помимо проблем с управлением памятью, в коде OP есть и другие проблемы (даже в том, что опубликован как ответ):

int next_prime(int last)
{
    printf("%i ", last);
    bool isPrime = false;
    do {
        last++;
        for (int i = 0; i < array_lenght; i++) {
            if (last % PRIME_ARRAY[i] != 0) isPrime = true; break;
            //                            ^^^^^^^^^^^^^^^^^^^^^^^^          
        }
    } while (!isPrime);
    return last;
}

Из-за отсутствия скобок, необходимых для определения области действияВ предложении if вложенный цикл for на самом деле не является циклом, и вся функция действует так, как если бы она была записана как:

int next_prime(int last)
{
    printf("%d ", last);
    do {
        last++;  
    } while (last % PRIME_ARRAY[0] == 0);
    return last;
}

На самом деле они оба генерируют неправильный вывод:все шансы, а не только простые числа.Например, первые 20 найденных чисел:

2 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39

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

Легким исправлением без добавления какой-либо другой глобальной переменной (их уже слишком много) может быть следующий фрагмент:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

int next_prime(int last);

int *PRIME_ARRAY, array_length;

int main(void)
{
    printf("How many prime numbers do you want to print? ");

    if (scanf("%d", &array_length) != 1  ||  array_length < 1)
        return EXIT_FAILURE;

    // Allocate and initialize to zero the array of primes
    PRIME_ARRAY = calloc(array_length + 1, sizeof *PRIME_ARRAY);
    if (!PRIME_ARRAY)
        return EXIT_FAILURE;

    int last = 0;
    for (int i = 0; i < array_length; i++)
    {
        // First find the next prime, then print it. Move all the
        // update logic to the called function
        last = next_prime(last);
        printf("%d ", last);
    }
    putchar('\n');

    free(PRIME_ARRAY);

    return EXIT_SUCCESS;
}

int next_prime(int last)
{
    bool has_factors;
    int i;
    do {
        ++last;
        has_factors = false;
        // Check only the known primes
        for (i = 0; PRIME_ARRAY[i] != 0; i++)
        {
            if (last % PRIME_ARRAY[i] == 0)
            {
                has_factors = true;
                break;
            }
        }
    } while ( has_factors  ||  last <= 1 );
    // Update here the array of primes, if there's space left
    if ( i < array_length )
        PRIME_ARRAY[i] = last;

    return last;
}
0 голосов
/ 24 декабря 2018

Храните PRIME_ARRAY как локальную, а не глобальную переменную.Затем измените список аргументов next_prime, чтобы включить базовый адрес массива и его размер.Вы используете sizeof, который дает размер базового указателя, который является размером слова на вашем компьютере.Вместо этого вам нужно передать переменную quantita в функцию next_prime.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...