使用指针的指针来创建一个动态的字符数组



我正在尝试为指针创建一系列指针,至少要熟悉我的理解。但是我的阅读量是无效的,并在Valgrind运行中写作。

char **format_file(FILE *infile) {
     char **char_array = malloc(20 * sizeof(char*));
     int c;
     int cUsed = 0;
     while ((c = fgetc(infile)) != EOF) {
         char_array[cUsed] = c;
         cUsed += 1;
     }
     printf("%s", *char_array);
     return char_array;
}

该代码通过从已经打开的文件" Infile"中读取来起作用。首先,我用malloc分配了20个字符的内存,然后我试图通过字符读取文件字符到分配的内存数组中,直到达到EO F。但是,Valgrind的输出如下:

==7379== Invalid read of size 1
==7379==    at 0x4E7CB36: vfprintf (vfprintf.c:1597)
==7379==    by 0x4E85198: printf (printf.c:35)
==7379==    by 0x400755: format_file (formatter.c:27)
==7379==    by 0x4006C1: main (format265alt.c:21)
==7379==  Address 0x6f is not stack'd, malloc'd or (recently) free'd

第27行是Valgrind的printf命令,它称为尺寸1的无效读数。

formatter.c是包含 format_file函数的文件,而格式化265alt.c是一个调用formatter.c函数并打开要读取的文件的文件。

我对**的语法感到困惑,也就是说,如何访问和读/写分配的内存?

如果我没有提供有关此问题的足够信息,我深表歉意。

valgrind抱怨,因为您在分配对象的末尾存储字符。编译器应抱怨您将字符存储到错误类型的对象中,使用-Wall -W启用有用的警告。

char **是指向炭指针的指针,它可以指向一系列的炭指针,也称为一系列字符串。您必须为文件内容分配数组和每个字符串。

这里有2种可能性:

  • 该函数可以将整个文件加载到一个字符串中,但是无需将指针返回到char*,只需返回字符串(char *)就足够了。

  • 如果函数要返回一个指针转换为一系列字符串的指针,则每行,最后一个NULL在末尾,就像argv数组将第二个参数传递给了该字符串,更合适main功能。

为此,您必须重新分配字符串数组,因为从FILE*读取更多行,并且随着其成长,每行应重新分配。在字符串数组的末尾添加NULL指针以指示其末端。

这是一种非常低效的方法:

#include <stdlib.h>
#include <stdio.h>
char **format_file(FILE *infile) {
      size_t lines = 0;
      char **array = malloc(1 * sizeof(char*));
      size_t pos = 0;
      char *line = malloc(1);
      int c;
      while ((c = getc(infile)) != EOF) {
          if (c == 'n') {
              line[pos] = '';
              array = realloc(array, (lines + 2) * sizeof(char *));
              array[lines++] = line;
              line = malloc(1);
              pos = 0;
              continue;
          }
          line = realloc(line, pos + 2);
          line[pos++] = c;
    }
    if (pos > 0) {
        line[pos] = '';
        array = realloc(array, (lines + 2) * sizeof(char *));
        array[lines++] = line;
    } else {
        free(line);
    }
    array[lines] = NULL;
    return array;
}

如果您只是创建字符数组,则一维字符数组就足够了。无需char**业务。但是,如果要将其用作字符串,请确保终止数组。

相关内容

  • 没有找到相关文章

最新更新