C 使用大输入文件时使用三角形软件分割错误

C 使用大输入文件时使用三角形软件分割错误,c,C,我正在使用三角形软件(二维质量网格生成器和Delaunay三角剖分器)()进行网格生成。它是开源的 当我试图使用大小为24 GB的639896119个节点的.node文件创建网格时,我遇到了分割错误。我不确定这是因为内存,我的机器是32 GB内存,所以我在504 GB内存的超级计算机上运行它。它也给出了分割错误 .node文件是格式为的文本文件 1 x1 y1 z1 2 x2 y2 z2 ... gdb调试在函数readnodes()的第14029行给出了分段错误。我使用pri

我正在使用三角形软件(二维质量网格生成器和Delaunay三角剖分器)()进行网格生成。它是开源的

当我试图使用大小为24 GB的639896119个节点的.node文件创建网格时,我遇到了分割错误。我不确定这是因为内存,我的机器是32 GB内存,所以我在504 GB内存的超级计算机上运行它。它也给出了分割错误

.node文件是格式为的文本文件

    1 x1 y1 z1
    2 x2 y2 z2
...
gdb调试在函数readnodes()的第14029行给出了分段错误。我使用prinft()查看它何时崩溃,它最多可以读取103025230行。readnoedes()用于读取.node文件的每一行

我在这里附加了readnodes()函数。分割发生的线被标记为: //帮助,gdb在读了很多行之后给出了分段错误

非常感谢您的帮助

/*****************************************************************************/
/*                                                                           */
/*  readnodes()   Read the vertices from a file, which may be a .node or     */
/*                .poly file.                                                */
/*                                                                           */
/*****************************************************************************/

#ifndef TRILIBRARY

#ifdef ANSI_DECLARATORS
void readnodes(struct mesh *m, struct behavior *b, char *nodefilename,
               char *polyfilename, FILE **polyfile)
#else /* not ANSI_DECLARATORS */
void readnodes(m, b, nodefilename, polyfilename, polyfile)
struct mesh *m;
struct behavior *b;
char *nodefilename;
char *polyfilename;
FILE **polyfile;
#endif /* not ANSI_DECLARATORS */

{
  FILE *infile;
  vertex vertexloop;
  char inputline[INPUTLINESIZE];
  char *stringptr;
  char *infilename;
  REAL x, y;
  int firstnode;
  int nodemarkers;
  int currentmarker;
  int i, j;

  if (b->poly) {
    /* Read the vertices from a .poly file. */
    if (!b->quiet) {
      printf("Opening %s.\n", polyfilename);
    }
    *polyfile = fopen(polyfilename, "r");
    if (*polyfile == (FILE *) NULL) {
      printf("  Error:  Cannot access file %s.\n", polyfilename);
      triexit(1);
    }
    /* Read number of vertices, number of dimensions, number of vertex */
    /*   attributes, and number of boundary markers.                   */
    stringptr = readline(inputline, *polyfile, polyfilename);
    m->invertices = (int) strtol(stringptr, &stringptr, 0);
    stringptr = findfield(stringptr);
    if (*stringptr == '\0') {
      m->mesh_dim = 2;
    } else {
      m->mesh_dim = (int) strtol(stringptr, &stringptr, 0);
    }
    stringptr = findfield(stringptr);
    if (*stringptr == '\0') {
      m->nextras = 0;
    } else {
      m->nextras = (int) strtol(stringptr, &stringptr, 0);
    }
    stringptr = findfield(stringptr);
    if (*stringptr == '\0') {
      nodemarkers = 0;
    } else {
      nodemarkers = (int) strtol(stringptr, &stringptr, 0);
    }
    if (m->invertices > 0) {
      infile = *polyfile;
      infilename = polyfilename;
      m->readnodefile = 0;
    } else {
      /* If the .poly file claims there are zero vertices, that means that */
      /*   the vertices should be read from a separate .node file.         */
      m->readnodefile = 1;
      infilename = nodefilename;
    }
  } else {
    m->readnodefile = 1;
    infilename = nodefilename;
    *polyfile = (FILE *) NULL;
  }

  if (m->readnodefile) {
    /* Read the vertices from a .node file. */
    if (!b->quiet) {
      printf("Opening %s.\n", nodefilename);
    }
    infile = fopen(nodefilename, "r");
    if (infile == (FILE *) NULL) {
      printf("  Error:  Cannot access file %s.\n", nodefilename);
      triexit(1);
    }
    /* Read number of vertices, number of dimensions, number of vertex */
    /*   attributes, and number of boundary markers.                   */
    stringptr = readline(inputline, infile, nodefilename);
    m->invertices = (int) strtol(stringptr, &stringptr, 0);
    stringptr = findfield(stringptr);
    if (*stringptr == '\0') {
      m->mesh_dim = 2;
    } else {
      m->mesh_dim = (int) strtol(stringptr, &stringptr, 0);
    }
    stringptr = findfield(stringptr);
    if (*stringptr == '\0') {
      m->nextras = 0;
    } else {
      m->nextras = (int) strtol(stringptr, &stringptr, 0);
    }
    stringptr = findfield(stringptr);
    if (*stringptr == '\0') {
      nodemarkers = 0;
    } else {
      nodemarkers = (int) strtol(stringptr, &stringptr, 0);
    }
  }

  if (m->invertices < 3) {
    printf("Error:  Input must have at least three input vertices.\n");
    triexit(1);
  }
  if (m->mesh_dim != 2) {
    printf("Error:  Triangle only works with two-dimensional meshes.\n");
    triexit(1);
  }
  if (m->nextras == 0) {
    b->weighted = 0;
  }

  initializevertexpool(m, b);

  /* Read the vertices. */
  for (i = 0; i < m->invertices; i++) {
    vertexloop = (vertex) poolalloc(&m->vertices);
    stringptr = readline(inputline, infile, infilename);
    if (i == 0) {
      firstnode = (int) strtol(stringptr, &stringptr, 0);
      if ((firstnode == 0) || (firstnode == 1)) {
        b->firstnumber = firstnode;
      }
    }
    stringptr = findfield(stringptr);
    if (*stringptr == '\0') {
      printf("Error:  Vertex %d has no x coordinate.\n", b->firstnumber + i);
      triexit(1);
    }
    x = (REAL) strtod(stringptr, &stringptr);
    stringptr = findfield(stringptr);
    if (*stringptr == '\0') {
      printf("Error:  Vertex %d has no y coordinate.\n", b->firstnumber + i);
      triexit(1);
    }
    y = (REAL) strtod(stringptr, &stringptr);
    vertexloop[0] = x; // HELP, gdb gave segmentation fault here after reading a lot lines.  
    vertexloop[1] = y;
    /* Read the vertex attributes. */
    for (j = 2; j < 2 + m->nextras; j++) {
      stringptr = findfield(stringptr);
      if (*stringptr == '\0') {
        vertexloop[j] = 0.0;
      } else {
        vertexloop[j] = (REAL) strtod(stringptr, &stringptr);
      }
    }
    if (nodemarkers) {
      /* Read a vertex marker. */
      stringptr = findfield(stringptr);
      if (*stringptr == '\0') {
        setvertexmark(vertexloop, 0);
      } else {
        currentmarker = (int) strtol(stringptr, &stringptr, 0);
        setvertexmark(vertexloop, currentmarker);
      }
    } else {
      /* If no markers are specified in the file, they default to zero. */
      setvertexmark(vertexloop, 0);
    }
    setvertextype(vertexloop, INPUTVERTEX);
    /* Determine the smallest and largest x and y coordinates. */
    if (i == 0) {
      m->xmin = m->xmax = x;
      m->ymin = m->ymax = y;
    } else {
      m->xmin = (x < m->xmin) ? x : m->xmin;
      m->xmax = (x > m->xmax) ? x : m->xmax;
      m->ymin = (y < m->ymin) ? y : m->ymin;
      m->ymax = (y > m->ymax) ? y : m->ymax;
    }
  }
  if (m->readnodefile) {
    fclose(infile);
  }

  /* Nonexistent x value used as a flag to mark circle events in sweepline */
  /*   Delaunay algorithm.                                                 */
  m->xminextreme = 10 * m->xmin - 9 * m->xmax;
}

#endif /* not TRILIBRARY */


/*****************************************************************************/
/*                                                                           */
/*  poolalloc()   Allocate space for an item.                                */
/*                                                                           */
/*****************************************************************************/

#ifdef ANSI_DECLARATORS
VOID *poolalloc(struct memorypool *pool)
#else /* not ANSI_DECLARATORS */
VOID *poolalloc(pool)
struct memorypool *pool;
#endif /* not ANSI_DECLARATORS */

{
  VOID *newitem;
  VOID **newblock;
  unsigned long alignptr;

  /* First check the linked list of dead items.  If the list is not   */
  /*   empty, allocate an item from the list rather than a fresh one. */
  if (pool->deaditemstack != (VOID *) NULL) {
    newitem = pool->deaditemstack;               /* Take first item in list. */
    pool->deaditemstack = * (VOID **) pool->deaditemstack;
  } else {
    /* Check if there are any free items left in the current block. */
    if (pool->unallocateditems == 0) {
      /* Check if another block must be allocated. */
      if (*(pool->nowblock) == (VOID *) NULL) {
        /* Allocate a new block of items, pointed to by the previous block. */
        newblock = (VOID **) trimalloc(pool->itemsperblock * pool->itembytes +
                                       (int) sizeof(VOID *) +
                                       pool->alignbytes);
        *(pool->nowblock) = (VOID *) newblock;
        /* The next block pointer is NULL. */
        *newblock = (VOID *) NULL;
      }

      /* Move to the new block. */
      pool->nowblock = (VOID **) *(pool->nowblock);
      /* Find the first item in the block.    */
      /*   Increment by the size of (VOID *). */
      alignptr = (unsigned long) (pool->nowblock + 1);
      /* Align the item on an `alignbytes'-byte boundary. */
      pool->nextitem = (VOID *)
        (alignptr + (unsigned long) pool->alignbytes -
         (alignptr % (unsigned long) pool->alignbytes));
      /* There are lots of unallocated items left in this block. */
      pool->unallocateditems = pool->itemsperblock;
    }

    /* Allocate a new item. */
    newitem = pool->nextitem;
    /* Advance `nextitem' pointer to next free item in block. */
    pool->nextitem = (VOID *) ((char *) pool->nextitem + pool->itembytes);
    pool->unallocateditems--;
    pool->maxitems++;
  }
  pool->items++;
  return newitem;
}

/*****************************************************************************/
/*                                                                           */
/*  pooldealloc()   Deallocate space for an item.                            */
/*                                                                           */
/*  The deallocated space is stored in a queue for later reuse.              */
/*                                                                           */
/*****************************************************************************/

#ifdef ANSI_DECLARATORS
void pooldealloc(struct memorypool *pool, VOID *dyingitem)
#else /* not ANSI_DECLARATORS */
void pooldealloc(pool, dyingitem)
struct memorypool *pool;
VOID *dyingitem;
#endif /* not ANSI_DECLARATORS */

{
  /* Push freshly killed item onto stack. */
  *((VOID **) dyingitem) = pool->deaditemstack;
  pool->deaditemstack = dyingitem;
  pool->items--;
}

vertexloop
由自定义函数按以下方式分配:

vertexloop = (vertex) poolalloc(&m->vertices);
您应该测试
vertexloop
是否为
NULL
,并使用有意义的消息中止


如果这告诉您无法分配内存,请调查
poolalloc
以查看是否存在导致大型计算机上分配失败的限制,这些限制可能由操作系统通过配额施加。用
malloc
编写一个简单的分配测试,看看它什么时候失败。

?(或类似)什么是
poolalloc
,为什么对它返回的内存没有错误检查?poolalloc()是一个分配内存的函数,它们也有一个函数pooldealloc(),但它不在readnodes()中使用。我还包括上面提到的。我想这就是问题所在。但我不知道如何在内部使用pooldealloc()。阅读每一行时,如果每次都执行poolalloc()和pooldealloc(),它会慢吗?@MitchWheat,这是Valgrind的输出。有什么想法吗?谢谢你的评论@chqrlie。事实上,我以前试过。有趣的是,当抛出分段错误时,vertexloop不是空的。在错误行
vertexloop[0]=x
之前,我使用gdb打印vertexloop[0]和vertexloop[1]的值,vertexloop[0]=1.296e(-309)(一个非常小的数字),vertexloop[1]=0。
vertexloop = (vertex) poolalloc(&m->vertices);