【问题标题】:Segmentation fault when initializing memory for pointer to array passed to a function为传递给函数的数组的指针初始化内存时出现分段错误
【发布时间】:2014-12-31 16:34:11
【问题描述】:

我正在编写一个函数,它创建一组小于传递给它的限制的素数。出于某种原因,我无法正确进行内存管理;我不断收到“分段错误: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;
}

【问题讨论】:

  • 你试过调试吗?当调试器出现段错误时,你在哪一行?
  • 以下是您如何自己调试的示例:stackoverflow.com/a/4717073/19719
  • 它不会触发段错误,但memset(marked, 0, *limit*sizeof(int)); 可能会更好。
  • 在第二个循环中,for(int num = 2; num &lt; *limit; num++){*limit 发生了变化,不再是marked 的长度。如果numPrime 高于*limit,它可能会触发段错误......虽然这不太可能......

标签: c memory memory-leaks segmentation-fault


【解决方案1】:

你的问题的根源是:

*primes[count] = num;

它尝试到达primes[count],但在到达count&gt;0 时立即失败。 要纠正这个:

(*primes)[count] = num;

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

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

  • 在第二个循环中,for(int num = 2; num &lt; *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;

如果它在大量数字上失败,请考虑溢出。

【讨论】:

  • 非常感谢!现在完美运行。
猜你喜欢
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多