【问题标题】:Error while freeing memory in C after program giving correct answer程序给出正确答案后在 C 中释放内存时出错
【发布时间】:2013-08-26 21:04:54
【问题描述】:

所以这是素数筛的代码,它给出了正确的输出,完全符合我的要求,除了打印正确结果后出现的丑陋错误。

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

void prime_gen(int *, int);
void show_primes(unsigned long, unsigned long, int *, int);

int main(void)
{
  int no_testcases=0;
  int count=0;
  unsigned long lower=0,upper=0;
  unsigned long size;

  size=sqrt(1000000000);
  printf("%lu\n", size);
  int * primes, *primes_temp;;
  primes=(int *)calloc(size+1,sizeof(int));
  assert (primes!=NULL);

  prime_gen(primes, size+1); /* generates array of 0 and 1's indicating if index is a prime number */

  scanf("%d", &no_testcases); /* no of test cases */
  while (count<no_testcases)
  {
    scanf("%lu %lu", &lower, &upper);
    show_primes(lower, upper, primes, size+1); /* shows all prime numbers in given range */
    count++;
    if (count!=no_testcases)
      putchar('\n');
  }

  free(primes);

  return 0;
}

还有输出:

31622
size=31623, set_index=63248, index=31625
1
1
10  
2
3
5
7
No of primes = 4
*** glibc detected *** ./a.out: double free or corruption (out): 0x09d49008 ***
a.out: malloc.c:2451: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Przerwane (core dumped)

这是素数生成器和 show_primes 的代码:

void prime_gen(int * tab, int size) /* 0== is prime, 1== is not prime */
{
  tab[0]=1;
  tab[1]=1;
  unsigned long index=2;
  unsigned long set_index;


  for(index=2;index<=size;index++)
  {
    while (index<=size && tab[index]!=0) /* goes to next prime number */
    {
      index++;
    }
    for(set_index=index+index;set_index<=size;set_index+=index)
      tab[set_index]=1;
  }
  printf("size=%d, set_index=%lu, index=%lu\n", size, set_index, index);
}

void show_primes(unsigned long l, unsigned long u, int * array, int size)
{
  int index = 0;
  int is_prime=1;
  int primes_count=0;

  for(l;l<=u;l++)
  {
    if (l<=size) /* if l is valid index of array with primes */
    {
      if(array[l]==0)
      {
    printf("%lu\n", l);
    primes_count++;

      }
    }
    else /* if checked number is bigger than last index of array */
    {
      is_prime=1;
      for (index=2;index<=size;index++)
      {
    if (array[index]==0)
    {
      if (l%index==0)
      {
        is_prime=0;
        break;
      }
    }
      }
      if (is_prime)
      {
    printf("%lu\n", l);
    primes_count++;

      }
    }

  }
  printf("No of primes = %d\n", primes_count);
}

我将其缩小为 free(primes) 作为问题,因为当删除错误消失并且程序按预期终止时。而且我知道数组在这里会更好,但是动态数组对我来说是新的,这应该是我对它们的教训。 非常感谢您的回答。

【问题讨论】:

  • 程序退出时将释放所有内存,因此快速的解决方案是让它退出。 ;) 问题:您是否使用任何优化或奇怪的设置进行编译?
  • 你确定你没有在 show_primes 函数中释放素数吗?你也可以放那个代码吗?
  • 显示prime_genshow_primes的定义。
  • 您正在索引数组,输入的大小为“size+1”,并将所有的索引都设为
  • @Jim 就是这样。将参数从 (size+1) 更改为 (size) 修复了代码。

标签: c arrays dynamic calloc


【解决方案1】:

我的猜测:

void prime_gen(int *, int);
void show_primes(unsigned long, unsigned long, int *, int);

int main(void)
{
  int no_testcases=0;
  int count=0;
  unsigned long lower=0,upper=0;
  unsigned long size;

  size=sqrt(1000000000);
  printf("%lu\n", size);
  int * primes, *primes_temp; *primes_head;
  primes=(int *)calloc(size+1,sizeof(int));
  primes_head = primes;
  assert (primes!=NULL);

  /* NOTE CHANGE BELOW */
  prime_gen(primes, size); /* generates array of 0 and 1's indicating if index is a prime number */

  scanf("%d", &no_testcases); /* no of test cases */
  while (count<no_testcases)
  {
    scanf("%lu %lu", &lower, &upper);
    /* NOTE CHANGE HERE */
    show_primes(lower, upper, primes, size); /* shows all prime numbers in given range */
    count++;
    if (count!=no_testcases)
      putchar('\n');
  }

  free(primes_head);

  return 0;
}

【讨论】:

  • 没有更多信息就不清楚了。也许 show_primes 正在改变素数 ptr ....
  • 如您所见,*primes_temp 是我尝试做同样事情的剩余部分。没有成功。
  • 您正在使用您的代码覆盖/覆盖素数。它可以工作,但指针已损坏。
  • Prime_gen(primes, size) NOT size+1
【解决方案2】:

prime_gen 函数中,你有这个:

for(set_index=index+index;set_index<=size;set_index+=index)
  tab[set_index]=1;

你的数组溢出了。在最后一次迭代中,您使用大于 sizeset_index 值写入元素 tab[set_index]

尝试将您的 for 循环停止条件更改为:set_index &lt; size

【讨论】:

    【解决方案3】:

    您正在调用 primes_genshow_primes 并使用 primes 数组和数组的大小。在这些函数中,您正在读取和写入超出数组边界的一个:

    for(set_index=index+index;set_index<=size;set_index+=index)
      tab[set_index] = 1;
    

    这会破坏您的数组,因此您对 free() 的调用失败。

    【讨论】:

      【解决方案4】:

      尝试将scanf("%lu %lu", &amp;lower, &amp;upper); 移出循环

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-28
        相关资源
        最近更新 更多