使用长数据类型时Malloc()失败

使用长数据类型时Malloc()失败,c,malloc,C,Malloc,下面的代码打印出[m,n]之间的所有素数。 当我使用unsigned int时,malloc在我的64位系统上可以完美地工作到10^9 #include <stdio.h> #include <string.h> #include <stdbool.h> #include <stdlib.h> #include <time.h> #define true 1 #define false 0 void

下面的代码打印出[m,n]之间的所有素数。 当我使用unsigned int时,malloc在我的64位系统上可以完美地工作到
10^9

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

  #define true 1 
  #define false 0

  void SieveOfEratosthenes(unsigned int m ,unsigned int n) {
      bool *prime;
      prime = (bool*)malloc(m - n + 2);
      if (!prime) {
          printf("FAIL\n");
          return;
      }
      memset(prime, true, (m - n + 2));
      unsigned int i = 2;
      for (i = 2; i * i <= n; i++) {
          if (prime[i] == true) {
              for (unsigned int j = i * 2; j <= n; j += i)
                  prime[j] = false;
          }
      }
      for (i = m; i <= n; i++)
          if (prime[i] && i != 1)
              printf("%u  \n", i);
  }

  int main() {
      clock_t begin,end;
      unsigned int m, n;
      scanf("%u %u", &m, &n);
      begin = clock();
      SieveOfEratosthenes(m, n);
      end = clock();
      double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
      printf("\nTime Taken : %lf secs\n", time_spent);
      return 0;
  }

由于以下原因,您的代码具有未定义的行为:

      unsigned int m, n;
      scanf("%llu %llu", &m, &n);
此外,您没有分配适当的内存量:

      prime = (bool*)malloc(m - n + 2);
如果
m
小于
n+2
,则大小将变成一个巨大的数字。它只适用于
unsigned int
,因为您可以在系统上分配4GB或16GB内存

事实上,给定您的算法,您必须分配
n+1
元素,因为在筛选过程中,您使用从2开始的数字对该数组进行索引

此外,对于这个数组,您应该使用
无符号字符
而不是
bool
,因为类型
bool
可以大于1字节

以下是修改后的版本:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

void SieveOfEratosthenes(unsigned long long m, unsigned long long n) {
    unsigned char *prime = malloc(n + 1);
    if (!prime) {
        printf("FAIL\n");
        return;
    }
    memset(prime, 1, n + 1);
    unsigned long long i, j;
    for (i = 2; i * i <= n; i++) {
        if (prime[i]) {
            for (j = i * 2; j <= n; j += i)
                prime[j] = 0;
        }
    }
    for (i = m; i <= n; i++) {
        if (prime[i] && i != 1)
            printf("%llu\n", i);
    }
}

int main() {
    clock_t begin, end;
    unsigned long long int m, n;
    if (scanf("%llu %llu", &m, &n) == 2) {
        begin = clock();
        SieveOfEratosthenes(m, n);
        end = clock();
        double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
        printf("\nTime Taken : %f secs\n", time_spent);
    }
    return 0;
}

您的系统上的
大小是多少?(正如
malloc
size\u t
作为输入)(代码审查:为什么不将
#包括
?)malloc还需要像->
malloc这样的大小(无论大小(数据类型))
。使用
sizeof()
运算符相应地分配内存。请显示您提供的产生不希望的输出的输入。您的大小计算为
m-n+2
,对于
m==1
n==100
为负值。您必须确保
m>=n
。(但是你的循环
i=m;i和OP应该从中得到警告。他正在使用malloc()-有大量未定义、未指定和实现定义的行为需要担心!这很尴尬,我意识到我是在做
m-n+2
而不是
n-m+2
。所以正如你所说,它是偶然为
unsigned int
工作的。我不明白为什么OP没有添加像
printf(“%llu%llu\n”,m,n)
malloc()之前(
(如果没有IDE调试器)。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

void SieveOfEratosthenes(unsigned long long m, unsigned long long n) {
    unsigned char *prime = malloc(n + 1);
    if (!prime) {
        printf("FAIL\n");
        return;
    }
    memset(prime, 1, n + 1);
    unsigned long long i, j;
    for (i = 2; i * i <= n; i++) {
        if (prime[i]) {
            for (j = i * 2; j <= n; j += i)
                prime[j] = 0;
        }
    }
    for (i = m; i <= n; i++) {
        if (prime[i] && i != 1)
            printf("%llu\n", i);
    }
}

int main() {
    clock_t begin, end;
    unsigned long long int m, n;
    if (scanf("%llu %llu", &m, &n) == 2) {
        begin = clock();
        SieveOfEratosthenes(m, n);
        end = clock();
        double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
        printf("\nTime Taken : %f secs\n", time_spent);
    }
    return 0;
}
void SieveOfEratosthenes(unsigned long long m, unsigned long long n) {
    unsigned int maxp = (unsigned int)(ceil(sqrt(n)) + 1);
    unsigned char *composite = calloc(maxp, 1);
    unsigned char *slice = calloc(n - m + 1, 1);
    if (!composite || !slice) {
        free(composite);
        free(slice);
        printf("FAIL\n");
        return;
    }
    /* compute the primes */
    unsigned int p, q;
    for (p = 2; p * p < maxp; p++) {
        if (!composite[p]) {
            for (q = p * 2; q < maxp; q += p)
                composite[p] = 1;
        }
    }
    /* sieve the slice */
    unsigned long long i;
    if (m == 0)
        slice[0] = 1;
    if (m <= 1 && n >= 1)
        slice[1 - m] = 1;
    for (p = 2; p < maxp; p++) {
        if (!composite[p]) {
            i = 2 * p;
            if (i < m) {
                i = m - m % p;
                if (i < m)
                    i += p;
            }
            while (i <= n) {
                slice[i - m] = 1;
                i += p;
            }
        }
    }
    for (i = m; i <= n; i++) {
        if (!slice[i - m])
            printf("%llu\n", i);
    }
    free(composite);
    free(slice);
}