C语言 递增阵列大小失败

bvuwiixz  于 2023-06-28  发布在  其他
关注(0)|答案(2)|浏览(111)

我试图写一个函数来向数组中添加素数,但我的realloc一直失败。有人能看看我的代码,告诉我为什么它失败了吗?

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

void makePrimes(int *primes, int *primesLength, int primeTarget);
int isPrime(int input);

int main(void)
{
    int *primes = (int *)(malloc(1));
    *primes = 2;
    int primesLength = 1;
    makePrimes(primes, &primesLength, 3);
    printf("%d", *(primes + 2));
    free(primes);
    return 0;
}

//* Finds the prime number that is the prime target number prime
//* (i.e 2 is the zeroth prime)
//! PRIME TARGET COUNTS FROM ZERO BUT  PRIMES LENGTH COUNTS FROM 1
void makePrimes(int *primes, int *primesLength, int primeTarget)
{
    // do nothing
    if (*primesLength >= primeTarget + 1)
        return;

    int lastValue = *(primes + (*primesLength - 1));
    while (primeTarget + 1 != *primesLength)
    {
        lastValue++;
        if (isPrime(lastValue))
        {
            (*primesLength)++;
            primes = realloc(primes, *primesLength * sizeof(int));
            *(primes + (*primesLength - 1));
        }
    }
}

//* Checks if a given integer is prime
int isPrime(int input)
{
    if (input == 0 || input == 1)
    {
        return 0;
    }
    int testFactor = 2;
    for (int iii = 0; iii < (input - 2); iii++)
    {
        if ((input % testFactor) == 0)
            return 0;
        testFactor++;
    }
    return 1;
}

我希望它向数组'primes'添加一个可用元素。使用调试器,我发现primes被设置为NULL,并且没有运行以下行。谢谢

0aydgbwb

0aydgbwb1#

1.你最初的malloc() 1字节,而不是sizeof(int) == sizeof *primes,在我的系统上是4
1.首选sizeof变量而不是类型。这意味着您不必重复类型,这使得代码在面对未来(类型)更改时不那么脆弱。
1.不要从malloc()强制转换void *
1.当你想改变primes(使用realloc())时,你需要传入&primesmakePrimes()
1.使用临时变量(tmp)作为realloc()的返回值,否则会在失败时泄漏内存。
1.检查malloc()realloc()的返回值。
1.将找到的值赋给primes
1.(不固定)你坚持使用指针而不是数组表示法,这让你自己更难了。
1.(未修复)考虑使用无符号类型。这消除了错误类。例如,如果primeTarget是负的,那么期望的输出是什么?如果传入一个负素数呢?

  1. isPrime()可以优化为只查看testFactor <= input / testFactor
    1.(未修复)考虑修改接口,使makePrimes()也填充第一个值,而不是依赖于调用者为*primes*primesLenght输入正确的魔法值。
    1.(不固定)当你指定你想要多少个素数时,你可以只预先分配primes数组,而不是一次增长数组成员。
    1.我做了一个printPrimes()函数,它更适合[调试;你用你原来的代码只是想要最后一个。如果你只想要最后一个质数,为什么要把剩下的都存储在数组中呢?
#include <stdio.h>
#include <stdlib.h>

int isPrime(int input) {
    if (input == 0 || input == 1)
        return 0;
    for (int testFactor = 2; testFactor <= input / testFactor; testFactor++) {
        if (!(input % testFactor))
            return 0;
    }
    return 1;
}

void makePrimes(int **primes, int *primesLength, int primeTarget) {
    if(*primesLength < 1)
        return;
    int lastValue = *(*primes + (*primesLength - 1));
    while (*primesLength < primeTarget) {
        lastValue++;
        if (isPrime(lastValue)) {
            int *tmp = realloc(*primes, sizeof *tmp * (*primesLength + 1));
            if(!tmp) {
                printf("realloc failed\n");
                return;
            }
            *primes = tmp;
            *((*primes) + *primesLength) = lastValue;
            (*primesLength)++;
        }
    }
}

void printPrimes(int n, int primes[n]) {
    if(n <= 0) return;
    printf("%d", *primes);
    for(int i = 1; i < n; i++)
        printf(", %d", *(primes+i));
    printf("\n");
}

int main(void) {
    int *primes = malloc(sizeof *primes);
    if(!primes) {
       printf("malloc failed\n");
       return 1;
    }
    *primes = 2;
    int primesLength = 1;
    makePrimes(&primes, &primesLength, 3);
    printPrimes(primesLength, primes);
    free(primes);
    return 0;
}

示例运行:

2, 3, 5
qacovj5a

qacovj5a2#

在注解中(//后的文本)有它被添加或更改的原因
upd:makePrimes' retvalue like realloc()

--- orig0.c
+++ orig1.c
@@ -1,16 +1,23 @@
 #include <stdio.h>
 #include <stdlib.h>
+#include <err.h>
 
-void makePrimes(int *primes, int *primesLength, int primeTarget);
+int* makePrimes(int *primes, int *primesLength, int primeTarget);
 int isPrime(int input);
 
 int main(void)
 {
-    int *primes = (int *)(malloc(1));
+    int *primes = (int *)(malloc(sizeof(int))); // allocate proper size
+    if (!primes) // test a result of malloc allocation
+        err(-1, "malloc");
     *primes = 2;
     int primesLength = 1;
-    makePrimes(primes, &primesLength, 3);
-    printf("%d", *(primes + 2));
+    primes = makePrimes(primes, &primesLength, 10);
+    if (primes) { // print all of them
+        for (int i = 0; i < primesLength; i++)
+            printf("%d ", primes[i]);
+        printf("\n");
+    }
     free(primes);
     return 0;
 }
@@ -18,11 +25,11 @@
 //* Finds the prime number that is the prime target number prime
 //* (i.e 2 is the zeroth prime)
 //! PRIME TARGET COUNTS FROM ZERO BUT  PRIMES LENGTH COUNTS FROM 1
-void makePrimes(int *primes, int *primesLength, int primeTarget)
+int* makePrimes(int *primes, int *primesLength, int primeTarget) // return pointer like realloc()
 {
     // do nothing
     if (*primesLength >= primeTarget + 1)
-        return;
+        return primes;
 
     int lastValue = *(primes + (*primesLength - 1));
     while (primeTarget + 1 != *primesLength)
@@ -30,11 +37,17 @@
         lastValue++;
         if (isPrime(lastValue))
         {
+            int *reallocated = realloc(primes, (*primesLength + 1) * sizeof(int));
+            if (!reallocated) { // test a result of realloc()
+                warn("realloc");
+                break;
+            }
+            primes = reallocated;
+            *(primes + *primesLength) = lastValue; // forgotten assignment
             (*primesLength)++;
-            primes = realloc(primes, *primesLength * sizeof(int));
-            *(primes + (*primesLength - 1));
         }
     }
+    return primes;
 }
 
 //* Checks if a given integer is prime

相关问题