我在程序的堆部分中分配函数的返回值时遇到问题。当我在main中尝试它时,它会出现错误“Segmentation fault”。我相信这是因为我的数组的大小,这是我之前提到的返回值,因为当我使我的max_size更小时,代码正常工作(我认为高达45000)。当我在main中调用函数时,它使用堆栈的内存,这比堆的内存小得多。因此,我尝试在堆中调用该函数并在那里进行赋值,但编译器发出错误
deneme.c:6:15: error: initializer element is not constant
int *primes = listPrimes(1000000, &size);
之后我做了一些研究,发现堆栈是8 MB内存,大约8000000字节。然后我估计我的数组大小使用素数定理(最多1000000,大约有200000个素数)和sizeof(int) = 4 bit
值,因此它给出100000字节,远小于8 MB。因此,我有两个问题:
1。虽然我的数组大小不是太大,但为什么编译器会出现分段错误错误?
2. 我如何在堆中而不是main中进行分配以避免此问题?
这是我的代码:
#include "mathlib.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
int *listPrimes(int max_size, int *size) {
*size = 1;
int *result = malloc(*size * sizeof(int));
int i;
int index = 1;
// Finding the list of primes using a sieve algorithm:
int *nums = malloc(max_size*sizeof(int));
for (i = 0; i < max_size; i++) {
nums[i] = i;
}
result[0] = 2;
int j = 2;
while (j < max_size) {
int k = j;
while (j*k <= max_size) {
nums[j*k] = 0;
k++;
}
if (j == 2) {
j++;
*size = *size + 1;
result = realloc(result, *size * sizeof(int));
result[index++] = nums[j];
}
else {
j += 2;
if (nums[j] != 0) {
*size = *size + 1;
result = realloc(result, *size * sizeof(int));
result[index++] = nums[j];
}
}
}
return result;
}
和主要功能:
#include <stdio.h>
#include <stdlib.h>
#include "mathlib.h"
int size = 0;
int *primes = listPrimes(1000000, &size);
int main() {
printf("size = %d\n", size);
for (int i = 0; i < size; i++) {
printf("%d th prime is %d\n", i+1, primes[i]);
}
free(primes);
return 0;
}
答案 0 :(得分:1)
nums
被分配为max_size
个元素,因此其最后一个元素的索引为max-size-1
。
这个循环:
while (j*k <= max_size) {
nums[j*k] = 0;
k++;
}
可以访问索引j*k
等于max_size
的元素,从而写入超出数组末尾的元素。循环应限制为j*k < max_size
。
关于你的第二个问题,result
数组的大小是在找到素数时确定的,并且不能提前计算,因此在调用listPrimes
之前不能轻易分配。{1}}数组。可以通过评估prime-counting function来完成,但这可能比您想要为此项目做的更多。
答案 1 :(得分:1)
在listPrimes中对unsigned int
和j, k
使用max_size
,它可以正常运行。以下是经过测试的代码:
// #include "mathlib.h"
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
int size = 0;
int *
listPrimes (unsigned int max_size, int *size)
{
*size = 1;
int *result = malloc (*size * sizeof (int));
int i;
int index = 1;
// Finding the list of primes using a sieve algorithm:
int *nums = malloc (max_size * sizeof (int));
for (i = 0; i < max_size; i++)
{
nums[i] = i;
}
result[0] = 2;
unsigned int j = 2;
while (j < max_size)
{
unsigned int k = j;
while (j * k <max_size)
{
nums[j * k] = 0;
k++;
}
if (j == 2)
{
j++;
*size = *size + 1;
result = realloc (result, *size * sizeof (int));
result[index++] = nums[j];
}
else
{
j += 2;
if (nums[j] != 0)
{
*size = *size + 1;
result = realloc (result, *size * sizeof (int));
result[index++] = nums[j];
}
}
}
free(nums);
return result;
}
int
main ()
{
int *primes = listPrimes (1000000, &size);
printf ("size = %d\n", size);
for (int i = 0; i < size; i++)
{
printf ("%d th prime is %d\n", i + 1, primes[i]);
}
free (primes);
return 0;
}