不可能的事情发生了!这是什么意思? [英] The Impossible Happened! What does this mean?

查看:55
本文介绍了不可能的事情发生了!这是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个有趣的运行时错误.我认为这是某种内存泄漏.我编写了以下程序:

I have experienced an interesting runtime error. I assume it is some sort of memory leak. I wrote the following program:

C代码:

C Code:

#include <gmp.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#define  PRECISION 4096
#define  DECIMAL_POINT 1
#define  NULL_TERMINATOR 1

void     gatherSquares(const uint32_t limit, uint32_t ** const arr, uint32_t * const count);
uint32_t inList(const uint32_t n, const uint32_t * const arr, const uint32_t count);
void     print_help(const char * const str);

int main(int argc, char* argv[]) {
  uint32_t limit  = 100; /* default */
  uint32_t digits = 100; /* default */
  uint32_t i,j,sum,bufLen,charCount,sqCount=10;
  uint32_t *squares;
  char     *buffer;
  mpf_t    irrational;

  if(argc > 1 && !strcmp(argv[1],"--help"))
    return print_help(argv[0]), EXIT_SUCCESS;
  if(argc > 1)    sscanf(argv[1],"%u",&limit );
  if(argc > 2)    sscanf(argv[2],"%u",&digits);

  mpf_set_default_prec(PRECISION);
  mpf_init(irrational);

  charCount = digits + DECIMAL_POINT;
  bufLen    = charCount + NULL_TERMINATOR;

  gatherSquares(limit,&squares,&sqCount);
  buffer  = malloc(bufLen * sizeof *buffer);

  for(i=sum=0; i<=limit; ++i) {
    if(inList(i,squares,sqCount))
      continue;
    mpf_sqrt_ui(irrational,i);
    gmp_snprintf(buffer,bufLen,"%.*Ff",charCount,irrational);
    for(j=0; j<digits+DECIMAL_POINT; ++j)
      if(buffer[j]!='.')
        sum += buffer[j]-'0';
  }
  printf("%u\n",sum);
  return EXIT_SUCCESS;
}

void gatherSquares(const uint32_t limit, uint32_t ** const arr, uint32_t * const count) {
  uint32_t i,sq,size;
  size=10;
  *arr   = malloc(size * sizeof **arr);
  for(i=0; (sq=i*i)<=limit; ++i) {
    if(*count > size)
      *arr = realloc(*arr, (size*=2) * sizeof **arr);
    (*arr)[i] = sq;
  }
  *arr = realloc(*arr, i * sizeof **arr);
  *count = i;
}

uint32_t inList(const uint32_t n, const uint32_t * const arr, const uint32_t count) {
  uint32_t hi,mid,low;
  hi  = count; /* exclusive upper bound */
  low = 0;     /* inclusive lower bound */
  while(low < hi) {
    mid = low/2 + hi/2;
    if(arr[mid]==n)
      return 1;
    if(arr[mid] >n)
      hi  = mid;
    else
      low = mid + 1;
  }
  return 0;
}

void print_help(const char * const str) {
  printf("  Usage: %s <limit> <digits>\n",str);
  printf("  Calculates the digital sum of the first <digits> digits \n");
  printf("  of each irrational square root <= <limit>\n");
  printf("  * limit    : a decimal number\n");
  printf("             : default = 100\n");
  printf("  * digits   : a decimal number\n");
  printf("             : default = 100\n");
}

我使用默认设置./a.out运行该程序,并且一切正常运行.然后,我决定尝试以更高的搜索空间./a.out 1000运行该程序.这产生了以下输出:

I ran the program with the default settings ./a.out and everything ran correctly. I then decided to try running the program with a higher search space ./a.out 1000. This produced the following output:

user@comp:~/Current/Working/Directory ./a.out 1000 
a.out: malloc.c:2369: 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.
Aborted (core dumped)

我认为必须存在一些内存泄漏,因此我启动了valgrind来帮助定位问题.我对输出感到震惊:

I assumed there must be some memory leak so I fired up valgrind to help locate the issue. I was dumbstruck by the output:

user@comp:~/Current/Working/Directory valgrind ./a.out 1000 
==4032== Memcheck, a memory error detector
==4032== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==4032== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==4032== Command: ./ans-0080 1000
==4032== 
==4032== Invalid write of size 4
==4032==    at 0x8048920: gatherSquares (prog.c:59)
==4032==    by 0x80486C4: main (prog.c:36)
==4032==  Address 0x427b288 is 0 bytes after a block of size 40 alloc'd
==4032==    at 0x402C418: malloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4032==    by 0x804890F: gatherSquares (prog.c:55)
==4032==    by 0x80486C4: main (prog.c:36)
==4032== 
--4032-- VALGRIND INTERNAL ERROR: Valgrind received a signal 11 (SIGSEGV) - exiting
--4032-- si_code=1;  Faulting address: 0x66656220;  sp: 0x625b8a80

valgrind: the 'impossible' happened:
   Killed by fatal signal
==4032==    at 0x380DA208: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==4032==    by 0x380DAAB1: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==4032==    by 0x38054133: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==4032==    by 0x38054206: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==4032==    by 0x38052115: ??? (in /usr/lib/valgrind/memcheck-x86-linux)
==4032==    by 0x20657360: ???

sched status:
  running_tid=1

Thread 1: status = VgTs_Runnable
==4032==    at 0x402C63E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==4032==    by 0x8048979: gatherSquares (prog.c:61)
==4032==    by 0x80486C4: main (prog.c:36)

注意行valgrind: the 'impossible' happened:!发生什么不可能的事情?这是什么意思?

Note the line valgrind: the 'impossible' happened:! What impossible thing happened? What does this mean?

PS:
如果您知道该程序是为什么编写的,请不要发布对该程序的引用,以便搜索引擎将其编入索引!

PS:
If you know what the program was written for, don't post references to that for search engines to index!

推荐答案

我怀疑这不是内存泄漏,但是您正在分配的缓冲区的开始或结束之前进行写入,因此覆盖了malloc用于维护其数据结构,从而导致malloc失败.

I suspect this isn't a memory leak, but that you're writing before the beginning or after the end of your allocated buffers and thus overwriting the data that malloc uses to maintain it's data structures, thus a failure in malloc.

我无法编译您的代码进行测试,但是在快速的视觉检查中,这看起来很可疑(在collectSquares()中):

I can't compile your code to test, but on a quick visual inspection, this looks suspicious (in gatherSquares()):

if(*count > size)
  *arr = realloc(*arr, (size*=2) * sizeof **arr);

您需要基于i进行重新分配,而不是* count指向.

You need to realloc based on i, not *count points to.

这篇关于不可能的事情发生了!这是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆