【问题标题】:Why do the pointers in my array point to the same string?为什么我的数组中的指针指向同一个字符串?
【发布时间】:2022-10-20 16:22:46
【问题描述】:

我试图了解为什么会发生问题。我有一个文件,从中读取了几行:

char *array_slave[128];

int i = 0;
while ((read = getline(&line, &len, fp)) != -1)
{
    if (strstr(line, "X") != NULL)
    {
        array_slave[i] = line;
        printf("%s\n",array_slave[i]);
        i++;
    }
}

经过这个循环,我知道 array_slave 包含 32 行:

size_t array_length(char *ptr[])
{
    size_t i=0;
    while(ptr[i]!=NULL){
        //printf("%d\n", i);
        //printf("%s\n",ptr[i]);
        i++;
    }
    return i;

}

现在,我只想打印array_slave 的最后 4 个元素。无论如何,我注意到它总是打印同一行:

for(int i=0; i<10;i++){
    printf("%s\n", array_slave[i]);
}

我认为这是因为在第一个周期中,i++ 操作移动了指针,所以现在它位于我不感兴趣的内存地址中。我怎样才能返回array_slave的原始位置?我想指向array_slave[0]array_slave[1]等等……

【问题讨论】:

    标签: arrays c pointers getline


    【解决方案1】:

    因为它们都指向同一个linearray_slave[i] = line;ith 位置为每个i 存储相同的地址。 line 指向的内存每次都会被新内容覆盖。您应该将 line 的内容复制到一个新位置并将该位置的地址存储在 array_slave 数组中。

    【讨论】:

    • 还要注意:除非由于前一行太短而发生重新分配 - 在这种情况下,先前存储的指针得到被邀请的
    【解决方案2】:

    除了先前答案提出的解决方案之外,还可以通过在将指针复制到 slave_array 后将 line 设置为 NULL 来解决问题:

    char *array_slave[128];
    
    int i = 0;
    while ((read = getline(&line, &len, fp)) != -1)
    {
        if (strstr(line, "X") != NULL)
        {
            array_slave[i] = line;
            line = NULL;  // HERE
            printf("%s
    ",array_slave[i]);
            i++;
        }
    }
    

    这将导致 getline()malloc() 在下次调用时产生一个新缓冲区。 请注意,当您不再需要它时,您必须 free() 每个 array_slave[i]

    【讨论】:

      【解决方案3】:

      在这条循环之后,我知道array_slave 包含 32 行

      这并不完全准确,它包含 32 个指向 char 的指针指向1line 的地址,它本身就是一个指向 char 的指针,它将指向一个唯一的内存位置,它不会改变它在循环中指向的位置,改变的是存储在那个内存位置的内容,它是该特定迭代中的读取行。


      因此,通过上述信息,您可以看到存储在array_slave 中的指针都将指向line,并在循环中重复打印其中的任何内容,以及line 中的内容包含2是您从文件中读取的最后一行。

      您需要做的是在每次迭代中将line 的内容复制到array_slave[i]

      //...
      if (strstr(line, "X") != NULL)
      {
          strcpy(array_slave[i], line); //<---
          printf("%s
      ",array_slave[i]);
          i++;
      }
      //...
      

      1 - 包含地址
      2 - 指向

      【讨论】:

        【解决方案4】:

        添加(最近,对于迟到的读者)另一种方法:跳过这个中间变量line完全并直接读入数组;为此,它必须适当地初始化,但是:

        char *array_slave[128] = { NULL };
        

        然后允许将这些行读取为

        getline(array_slave + i, &len, fp)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-05-11
          • 1970-01-01
          • 2021-06-28
          • 2021-06-28
          • 2014-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多