初始化内存时,分段错误指向传递给函数的数组的指针

时间:2014-11-04 17:11:38

标签: 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, &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;
}

1 个答案:

答案 0 :(得分:1)

问题的根源是:

*primes[count] = num;

它会尝试触及primes[count],但只要count>0就会失败。 要纠正这个:

(*primes)[count] = num;

还有其他一些要点可以得到正确的结果:

  • 要初始化marker,请执行memset(marked, 0, *limit*sizeof(int));。函数memset()来自string.h:它设置了第一个*limit*sizeof(int) bytes

  • 在第二个循环中,for(int num = 2; num < *limit; num++){*limit已更改,它不再是marked的长度。要删除此问题,*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;
}

multiplier不是必需的,可能会针对multiple+=base;

进行更改

如果高数字失败,请考虑溢出。

相关问题