C 初始化传递给函数的数组指针的内存时出现分段错误

C 初始化传递给函数的数组指针的内存时出现分段错误,c,memory,memory-leaks,segmentation-fault,C,Memory,Memory Leaks,Segmentation Fault,我正在编写一个函数,它创建的素数集小于传递给它的限制。由于某些原因,我在正确管理内存方面遇到了困难;我总是犯错误:11。代码如下: #include <stdio.h> #include <stdlib.h> void getPrimes(int** primes, int* limit); int main(void){ int primeLimit = 99; int* primes; getPrimes(&primes, &

我正在编写一个函数,它创建的素数集小于传递给它的限制。由于某些原因,我在正确管理内存方面遇到了困难;我总是犯错误:11。代码如下:

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

void getPrimes(int** primes, int* limit);

int main(void){
    int primeLimit = 99;
    int* primes;
    getPrimes(&primes, &primeLimit);

    //Do stuff

    free(primes);

    return 0;
}

void getPrimes(int** primes, int* limit){

    int multiplier; //Number used to multiply by to find numbers that do have factors
    int multiple; //Stores the current multiple
    int numPrimes = 0; //Number of primes (returned to caller)
    int count = 0;
    int* marked = (int*)malloc(*limit * sizeof(int)); //Initialize memory and sets it to 0
    memset(marked, 0, *limit);

    marked[0] = 1; //Set 0 and 1 to be not prime
    marked[1] = 1;

    for(int base = 2; base < *limit; base++){//Go through each number and mark all its multiples, start with 2
        if(!marked[base]){ //If base is already marked, its multiples are marked
            multiplier = 2; //Start multiple at 2
            multiple = base * multiplier; //Set first multiple for loop
            while(multiple < *limit){//Mark each multiple until limit reached
                marked[multiple] = 1;
                multiplier++;
                multiple = base * multiplier;
            }
        }
    }

    //Do a sweep to get the number of primes

    for(int num = 2; num < *limit; num++){//Go through each number and check if marked
        if(!marked[num]){ //Number is prime
            numPrimes++; //Increase count of primes if number is prime
        }
    }

    *limit = numPrimes; //update limit to the number of primes
    *primes = (int*)malloc(numPrimes * sizeof(int)); //Allocate memory for primes

    //Now actually put the primes in the array

    printf("Number of Primes: %d\n\n", numPrimes);

    for(int num = 2; num < *limit; num++){//Go through each number and check if marked
        printf("Num: %d, ", num); //Print it for debugging
        printf("Count: %d\n", count);
        if(!marked[num]){ //Number is prime
            *primes[count] = num; //Append to primes list (returned to caller)
            count++; //Increase count of primes if number is prime
        }
    }

    free(marked); //Free the memory used to mark multiples

    return;
}

问题的根源是:

*primes[count] = num;
它试图达到素数[count],一旦count>0,它就会失败。 要更正此问题,请执行以下操作:

(*primes)[count] = num;
要获得正确的结果,还有其他几点:

要初始化标记,请执行memsetmarked,0,*limit*sizeofint;。函数memset来自string.h:它设置第一个*limit*sizeofint

在第二个循环中,forint num=2;num<*限制;num++{,*limit已更改,不再是标记的长度。若要删除此问题,*limit的初始值可能存储在formerlimit中

代码如下:

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

void getPrimes(int** primes, int* limit);

int main(void){
    int primeLimit = 99;
    int* primes;
    getPrimes(&primes, &primeLimit);

    //Do stuff

    free(primes);

    return 0;
}

void getPrimes(int** primes, int* limit){

    int multiplier; //Number used to multiply by to find numbers that do have factors
    int multiple; //Stores the current multiple
    int numPrimes = 0; //Number of primes (returned to caller)
    int count = 0;
    int formerlimit=*limit;
    int* marked = (int*)malloc(*limit * sizeof(int)); //Initialize memory and sets it to 0
    memset(marked, 0, *limit);

    marked[0] = 1; //Set 0 and 1 to be not prime
    marked[1] = 1;

    for(int base = 2; base < *limit; base++){//Go through each number and mark all its multiples, start with 2
        if(!marked[base]){ //If base is already marked, its multiples are marked
            multiplier = 2; //Start multiple at 2
            multiple = base * multiplier; //Set first multiple for loop
            while(multiple < *limit){//Mark each multiple until limit reached
                marked[multiple] = 1;
                multiplier++;
                multiple = base * multiplier;
            }
        }
    }

    //Do a sweep to get the number of primes

    for(int num = 2; num < *limit; num++){//Go through each number and check if marked
        if(!marked[num]){ //Number is prime
            numPrimes++; //Increase count of primes if number is prime
        }
    }

    *limit = numPrimes; //update limit to the number of primes
    *primes = (int*)malloc(numPrimes * sizeof(int)); //Allocate memory for primes

    //Now actually put the primes in the array

    printf("Number of Primes: %d\n\n", numPrimes);

    for(int num = 2; num < formerlimit; num++){//Go through each number and check if marked
        printf("Num: %d, ", num); //Print it for debugging
        printf("Count: %d\n", count);
        if(!marked[num]){ //Number is prime
            (*primes)[count] = num; //Append to primes list (returned to caller)
            count++; //Increase count of primes if number is prime
        }
    }

    free(marked); //Free the memory used to mark multiples

    return;
}
乘法器不是必需的,可以更改为multiple+=base


如果它在高数字上失败,请考虑溢出问题。

您尝试过调试吗?当调试器出现故障时,您在哪一行上?下面是一个示例,说明如何自己调试它:它不会触发SEGFULT,但memsetmarked,0,*limit*sizeofint;可能更好。在第二个循环中,forint num=2;num<*limit;num++{,*limit已更改,不再是标记的长度。如果numPrime高于*limit,可能会触发segfault…但这不太可能…非常感谢!现在工作正常。