【问题标题】:how to store command line arguments into a dynamic string array in c如何将命令行参数存储到c中的动态字符串数组中
【发布时间】:2022-10-13 16:33:35
【问题描述】:

嗨,我正在尝试将未知数量的命令行参数存储到 c 中动态分配的字符串数组中。终端告诉我我有一个 segFault,我已经追踪到 strcpy 行(参见代码 1。)我尝试查看其他人的解决方案,但我仍然不确定我做错了什么,但我相信我有内存泄漏。

代码 1。

for (int j = fileLocCount+1; j < argc; j++){
    strcpy(filelist.array[filelist.used], argv[j]);
    filelist.used += 1;
    if (filelist.used == filelist.size){
        for (int i = 0; i < 100; i++)
          insertArray(&filelist, i);
    }
}
//printArray(&filelist);
freeArray(&filelist);

'filelist' 变量是一个名为 Array 的结构

typedef struct {
  char **array;
  size_t used;
  size_t size;
} Array;

并具有功能

void initArray(Array *a, size_t initialSize) {
  a->array = (char **) calloc(initialSize, 255);
  a->used = 0;
  a->size = initialSize;
}
void insertArray(Array *a, int element) {
  // a->used is the number of used entries, because a->array[a->used++] updates a->used only *after* the array has been accessed.
  // Therefore a->used can go up to a->size
  if (a->used == a->size) {
    a->size *= 2;
    a->array = realloc(a->array, a->size * sizeof(int));
  }
    a->array[a->used++] = a->array[element];
}
void freeArray(Array *a) {
  free(a->array);
  a->array = NULL;
  a->used = a->size = 0;
}

任何帮助都非常感谢

【问题讨论】:

  • calloc(initialSize, 255); ??? 255是什么
  • 首先,请解释为什么你需要制作有问题的副本......命令行的字符串(argv [ x ])在程序执行期间不会去任何地方......
  • array 定义为char** 时,这个a-&gt;array = (char **) calloc(initialSize, 255); 是错误的...元素大小必须与sizeof(char*) 匹配。此外,您需要为字符串分配内存。或者,您可以将 array 设为指向 char 数组的指针。
  • realloc(a-&gt;array, a-&gt;size * sizeof(int)); 是错误的。您的数组包含char * 元素,因此您需要realloc(a-&gt;array, a-&gt;size * sizeof(char *)); 如果您的指针大于您的整数,那么您将不会分配尽可能多的内存。段错误。如前所述,前面的calloc 调用中的255 是无稽之谈。
  • 命令行参数已经存储在字符串数组中;它被称为argv。将它与argc 一起使用,几乎所有这些都是不必要的。

标签: arrays c pointers dynamic


【解决方案1】:

你有矛盾(我认为两者都是错误的)?alloc

  a->array = (char **) calloc(initialSize, 255);
    a->array = realloc(a->array, a->size * sizeof(int));

a-&gt;array 是一个char **,所以是一个指向字符串的指针(它本身就是一个指向字符的指针),实现了一个字符串数组,每个字符串都是一个字符数组。

所以我不明白为什么每个指针需要 255 个字节。

指向 char 的指针数组中的每个指针(指向 char)都应该是指针的大小。所以你需要initialSize 乘以这里的指针大小

a->array = (char **) calloc(initialSize, sizeof(char *));

然后,您需要分配每个字符串本身(现在您只分配了指向它们的指针)

for(int i=0; i<initialSize; i++) a->array[i]=malloc(255*sizeof(char));

sizeof(char) 在这里更多是为了让代码更清晰,因为它是1。但是,你永远不会知道,有一天你的代码可能不得不在一台有 2 个字节的计算机上编译 char

所以第一个calloc应该是

a->array = (char **) calloc(initialSize, sizeof(char *));
for(int i=0; i<initialSize; i++) a->array[i]=malloc(255*sizeof(char));

而对于realloc,它也有同样的问题。虽然这一次,您没有为每个指针错误地分配 255 个字节,而是为每个指针分配了 sizeof(int) 个字节。

所以,realloc应该是

a->array = realloc(a->array, a->size * sizeof(char *));
for(int i=a->size/2; i<a->size; i++) a->array[i]=calloc(255, sizeof(char));

在这两种情况下,您的主要问题是缺少字符串本身的分配。在第一种情况下,您为指针分配了内存。大小错误(您为每个指针分配了 255 个字节,而通常 8 或 4 个就足够了,即sizeof(char *))。因此,您可能会添加足够多的内存来存储指针,这只是浪费内存。但是,您没有添加任何内存来将字符本身存储在每个字符串中。

在第二种情况下,同样的事情,但指针错误大小的内存分配是不同的。您为每个指针分配了sizeof(int) 字节,而您应该分配了sizeof(char *)。在那里,在大多数机器上,巧合的是,相同的东西(4 个字节),或者可能还不够(4 个字节而不是 8 个)。

注意

  • 我推测您的意思是为每个字符串分配 255 个字符(否则为什么会出现 255 个字符是个谜)
  • 我没有进行分配测试(在继续之前应该检查*alloc 是否返回空值)。
  • 我并没有真正检查代码的其余部分,因为这似乎是一个主要的段错误源。

【讨论】:

    【解决方案2】:

    您的内存分配错误。

    对于这样的情况,单个字符串的长度没有固定限制,您需要所谓的“锯齿状数组”。

    https://en.wikipedia.org/wiki/Jagged_array#:~:text=In%20computer%20science%2C%20a%20jagged,edges%20when%20visualized%20as%20output

    它是一个字符指针数组,其中每个字符指针指向一个存储实际字符串的字符数组。

    所以有两个分配步骤:

    1. 分配字符指针数组
    2. 为要存储的每个字符串分配字符数组

      第 1 步将如下所示:

      #define INITIAL_NUMBER_OF_POINTERS 8
      char** array = calloc(INITIAL_NUMBER_OF_POINTERS, sizeof *array);
      if (array == NULL) exit(1);
      

      第 2 步将(对于您要复制的每个字符串)如下所示:

      size_t sz = strlen(string_to_copy) + 1;
      array[i] = malloc(sz);
      if (array[i] == NULL) exit(1);
      strcpy(array[i], string_to_copy);
      

      之后您可以在array 上使用realloc 来存储额外的字符指针。

    【讨论】:

      猜你喜欢
      • 2014-04-30
      • 1970-01-01
      • 2021-08-19
      • 1970-01-01
      • 2017-12-21
      • 2018-04-12
      • 1970-01-01
      • 2017-11-15
      • 1970-01-01
      相关资源
      最近更新 更多