在C中动态调整数组大小时Valgrind错误

时间:2018-02-14 13:06:41

标签: c arrays pointers tree valgrind

我试图从文件中读取一个定义为

的值列表
0001Text here

其中0001是id,其余是标签。

正确读取文件并且该部分工作正常但是当我尝试将项目添加到数组时我动态调整大小Valgrind会出现以下错误:

==9005== Invalid read of size 8
==9005==    at 0x108DB0: processFile (in /trees)
==9005==    by 0x108BEE: main (in /trees)
==9005==  Address 0x521d368 is 0 bytes after a block of size 24 alloc'd
==9005==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9005==    by 0x10903E: growArray (in /trees)
==9005==    by 0x108D76: processFile (in /trees)
==9005==    by 0x108BEE: main (in /trees)
==9005== 
==9005== Invalid write of size 8
==9005==    at 0x108DD6: processFile (in /trees)
==9005==    by 0x108BEE: main (in /trees)
==9005==  Address 0x521d368 is 0 bytes after a block of size 24 alloc'd
==9005==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9005==    by 0x10903E: growArray (in /trees)
==9005==    by 0x108D76: processFile (in /trees)
==9005==    by 0x108BEE: main (in /trees)
==9005== 

我意识到错误在我在下面的代码中标记的行上,但我无法弄清楚为什么会发生这些错误。我认为这可能与未正确初始化的值有关,但我不确定是否正确。

#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>

typedef struct node {
          char  *label;
  unsigned int   n;
} NODE;
typedef NODE TREE;

int growArray(TREE **, int, int);
int processFile(FILE **, char *);

int main (int argc, char **argv) {
  FILE *fp;   /* the file pointer */

  processFile(&fp, argv[1]);
  return 0;
}

int processFile(char *filename) {
  if ((*fp = fopen(fileName, "r")) == NULL) {
      printf("Unable to read file: %d: %s\n", errno, strerror(errno));
      exit(1);
  }

  /* array to hold all nodes. The index is the nodeID */
  int SIZE = 1;
  TREE *nodes = (TREE *)calloc(SIZE, sizeof(NODE));

  if (nodes == NULL) {
    fprintf(stderr, "Cannot allocate initial memory for array.\n");
    exit(1);
  }

  /* checks the line is 4 digits, followed by 63 characters that aren't a */
  /* carriage return or newline                                           */
  int id; char text[64];
  while (fscanf(*fp, " %4d%63[^\r^\n] ", &id, text) == 2){
    SIZE = growArray(&nodes, SIZE, id);

    /* ----------error line---------- */
    nodes[id].label = (char *)realloc(nodes[id].label, (strlen(text)+1));

    strcpy(nodes[id].label, text);

    fprintf(stderr, "%5d: %s\n", id, text);
    return 0;
  }
}

int growArray(TREE **array, int curSize, int id) {
  if (curSize > id) return curSize;

  TREE *temp = (TREE *)realloc(*array, (id * sizeof(NODE)));

  if (temp == NULL) {
    fprintf(stderr, "Cannot allocate more memory.\n");
    exit(1);
  } else {
    *array = temp;
  }
  return id;
}

我在哪里错了,我该怎么做才能解决这些问题?

1 个答案:

答案 0 :(得分:1)

C中的数组索引从零开始。您将nodes数组的大小调整为id的大小,然后访问nodes[id]。它不存在,因为它超出范围[0,id-1]。因此,有效元素为nodes[0]nodes[id-1]