【问题标题】:Creating a dynamic char array创建动态字符数组
【发布时间】:2019-09-16 10:25:50
【问题描述】:

我正在尝试读取文件并将单词存储到动态字符数组中。现在我遇到了分段错误(核心转储)错误。

我尝试过使用 strdup() 和 strcpy() 仍然遇到同样的错误

char ** array;

int main(int argc, char * argv[]){
    int size = 0;
    int i;
    FILE * file;
    char * line;
    size_t len;
    ssize_t read;


    file = fopen("wordsEn.txt", "r");
    if(file == NULL){
            printf("Error coudl not open wordsEn.txt\n");
            return -1;
    }

    while((read = getline(&line, &len, file)) != -1){
            size++;
    }

    array = (char **) malloc((sizeof(char *) * size));
    rewind(file);

    i = 0;
    while((read = getline(&line, &len, file)) != -1){
            //strcpy(array[i], line);
            array[i] = strdup(line);
            i++;
    }

    for(i = 0; i < size; i++){
            printf("%s", array[i]);
    }
}

我期望例如 array[0] 返回字符串 'alphabet'

【问题讨论】:

  • 将单词存储到动态字符数组中——这是什么意思? array[0] 是第一个词,array[1] 第二个,array[2] 第三个,...?
  • @Swordfish 是的,array[0] 是第一个单词。
  • 请注意,getline() 不是标准 C。
  • 如果你有兴趣,我把你的代码的完整修正版本放了
  • line 在其地址传递给 getline() 之前未初始化。 POSIX getline() 函数取消引用它接收到的地址并使用该值来决定如何表现(如果值是 NULL 它调用 malloc(),如果值不是 NULL 它被假定为返回的缓冲区malloc())。由于linemain() 中未初始化,这导致getline() 具有未定义的行为。

标签: c file char dynamic-arrays


【解决方案1】:

我收到分段错误(核心转储)错误。

警告每次您必须将 line 重置为 NULL 并将 len 重置为 0 时,通过 getline 获取新分配的行,对于实例:

while(line = NULL, len = 0, (read = getline(&line, &len, file)) != -1){

注意你不必读取两次文件,你可以使用 malloc 然后 realloc 来增加(真正的)动态数组的大小


提案:

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

int main()
{
  char ** array = malloc(0);
  size_t size = 0;
  FILE * file;
  char * line;
  size_t len;
  ssize_t read;

  file = fopen("wordsEn.txt", "r");
  if(file == NULL) {
    printf("Error coudl not open wordsEn.txt\n");
    return -1;
  }

  while (line = NULL, len = 0, (read = getline(&line, &len, file)) != -1){
    array = realloc(array, (size+1) * sizeof(char *));
    array[size++] = line;
  }
  free(line); /* do not forget to free it */
  fclose(file);

  for(size_t i = 0; i < size; i++){
    printf("%s", array[i]);
  }

  /* free resources */
  for(size_t i = 0; i < size; i++){
    free(array[i]);
  }
  free(array);

  return 0;
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall ar.c
pi@raspberrypi:/tmp $ cat wordsEn.txt 
turlututu foo
bar
loop
pi@raspberrypi:/tmp $ ./a.out
turlututu foo
bar
loop
pi@raspberrypi:/tmp $ 

在 valgrind 下执行:

pi@raspberrypi:/tmp $ valgrind ./a.out
==13161== Memcheck, a memory error detector
==13161== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13161== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==13161== Command: ./a.out
==13161== 
turlututu foo
bar
loop
==13161== 
==13161== HEAP SUMMARY:
==13161==     in use at exit: 0 bytes in 0 blocks
==13161==   total heap usage: 11 allocs, 11 frees, 5,976 bytes allocated
==13161== 
==13161== All heap blocks were freed -- no leaks are possible
==13161== 
==13161== For counts of detected and suppressed errors, rerun with: -v
==13161== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 6 from 3)

【讨论】:

  • @xing 这正是我在想的 ;-)
  • @xing 是的,当我第一次读错 fgets 而不是 getline 时,我编辑了我的答案
  • @xing 这是我所做的,我编辑了我的答案以提供完整版
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-29
  • 2012-02-15
  • 2011-08-21
  • 2019-04-18
  • 2023-03-16
  • 2022-11-18
  • 1970-01-01
相关资源
最近更新 更多