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

标签 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;
}

我哪里出了问题,我能做些什么来解决这些问题?

最佳答案

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

关于c - 在 C 中动态调整数组大小时 Valgrind 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48788002/

相关文章:

c++ - C 简单 RingBuffer - 多线程 - 查找关键部分

c - 打印随机数而不是我的变量

c - 将进程置于前台

javascript - 返回多维数组 0 的函数

c - 为什么在下面的函数中递增数组 "a"不是错误?

c - 当直接使用fputs在文件中写入字符数组时,会存储不同格式的文本

Javascript:数组中的对象有 undefined variable ?

java - 将 Char 读入数组

c - 关于我的C程序跳过空行的问题

c++ - 为什么我得到 EXC_BAD_ACCESS 即使指针看起来有效?