【问题标题】:generating a new array within a loop在循环中生成一个新数组
【发布时间】:2013-10-24 19:37:53
【问题描述】:

我正在用 C 语言做一个关于表示多行文本的小程序实验。

我想出了四种方式:数组数组、指针数组、数组指针、指针指针。

我在数组指针方面遇到了一个小问题。每次我创建一个数组时,它实际上只是重用了我已经创建的数组。

查看我程序的“数组指针”(pa) 部分的输出,了解我的意思:

variable    address         value
==========  ==============  =====
pa          0x10f500970

*(pa+0)     0x7fff6f0334bd

*(pa+0)[0]  0x7fff6f0334bd  t
*(pa+0)[1]  0x7fff6f0334be  e
*(pa+0)[2]  0x7fff6f0334bf  s
*(pa+0)[3]  0x7fff6f0334c0  t
*(pa+0)[4]  0x7fff6f0334c1
*(pa+0)[5]  0x7fff6f0334c2  0

*(pa+1)     0x7fff6f0334bd

*(pa+1)[0]  0x7fff6f0334bd  t
*(pa+1)[1]  0x7fff6f0334be  e
*(pa+1)[2]  0x7fff6f0334bf  s
*(pa+1)[3]  0x7fff6f0334c0  t
*(pa+1)[4]  0x7fff6f0334c1
*(pa+1)[5]  0x7fff6f0334c2  1

看看每个数组的地址是一样的吗?不是很酷,是吗?

所以这是我的问题:有没有办法在 n > 1 循环中实际声明一个新数组,而不是重写已经存在的数组的内容?

这里是snipplet:(LIST_SIZE = 2 and TEXT_SIZE = 6)

void** pa = malloc(LIST_SIZE * sizeof(void*));

printh();

printf("pa\t\t%p\n\n", pa);

for(int i = 0; i < LIST_SIZE; i++)
{
  char txt[TEXT_SIZE + 1];

  sprintf(txt, "test %d", i);

  *(pa + i) = txt;

  printf("*(pa+%d)\t\t%p\n\n", i, *(pa + i));

  for(int j = 0; j < TEXT_SIZE; j++){
    printf("*(pa+%d)[%d]\t%p\t%c\n", i, j, &(((char*)*(pa+i))[j]), ((char*)*(pa+i))[j]);
  }

  printf("\n");
}

谢谢。如果您有任何其他的 cmets 或建议,我也有兴趣听听。

完整的源代码在:https://gist.github.com/80m/7143558

【问题讨论】:

    标签: c arrays loops variable-declaration


    【解决方案1】:

    变量txtfor 循环的本地变量。在每次迭代中,旧的txt 变量将失效,并创建一个不同的txt 实例。这意味着在上一次迭代中分配的指针txt 在下一次迭代开始时未指向有效对象。

    当循环结束时,你的指针都不指向任何有效的东西。

    解决此问题的一种方法是为要分配的每个指针动态分配内存。

        pa[i] = malloc(TEXT_SIZE+1);
        snprintf(pa[i], TEXT_SIZE+1, "test %d", i);
    

    您说您想要“指向数组的指针”,但您声明了void **pa,这使得pa 成为指向指针的指针。如果你想让pa 指向一个数组的指针,你可以这样声明:

    char (*pa)[TEXT_SIZE+1] = malloc(LIST_SIZE * sizeof(*pa));
    

    所以现在,pa[0] 将是一个 7 字节数组,pa[1] 将是第二个 7 字节数组。您无需在循环中进行任何动态分配。

    【讨论】:

    • 是的,但这不会把“数组指针”变成“指针指针”吗?
    • 如果一个指针变量被分配了一个对象的地址,它就指向这个对象。对象是否动态分配都没有关系。解引用指针获得指向的对象。
    • 好吧,首先您提供的代码无法编译(pa + i 需要取消引用)。其次,指向的数组在哪里?你可能会做一些事情,但我需要做更多的实验。
    • @80m:很抱歉。我的大脑不是一个高质量的 C 编译器。
    • 您的编辑似乎是正确的。我印象深刻。你是怎么想到的?我认为这将是一个 char* 数组。
    【解决方案2】:

    每次循环运行时pa都指向同一个txt。因此,指针 pa 指向的地址保持不变。如果您想将其指向另一个位置,请尝试创建一个不同的 char[],例如 txt1,并在第二次迭代期间将其分配给 (pa+i)

    我试过了:

    int i=0,j=0;
    
    void** pa = malloc(LIST_SIZE * sizeof(void*));
    
    printf("pa\t\t%p\n\n", pa);
    
    for(i = 0; i < LIST_SIZE; i++)
    {
    
    char txt[TEXT_SIZE + 1];
    char txt1[TEXT_SIZE + 1];
    
    
      sprintf(txt1, "test %d", i);
      sprintf(txt, "test %d", i);
      if (i==0)
      {
        *(pa + i) = txt;
      }
      else
      {
        *(pa + i) = txt1;
      }
    
      printf("*(pa+%d)\t\t%p\n\n", i, *(pa + i));
    
      for(j = 0; j < TEXT_SIZE; j++){
        printf("*(pa+%d)[%d]\t%p\t%c\n", i, j, &(((char*)*(pa+i))[j]), ((char*)*(pa+i))[j]);
      }
    
      printf("\n");
    }
    

    并为不同的迭代获得不同的地址。

    我认为问题不在于指针,而在于它试图引用的变量,并且每次都保持相同的变量。希望这会有所帮助!

    【讨论】:

    • 是的,但是如果我将 LIST_SIZE 更改为 3 会怎样?除了这次使用 txt1 变量之外,也会出现同样的问题。
    猜你喜欢
    • 2020-10-09
    • 2011-09-23
    • 2018-07-16
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 1970-01-01
    • 2023-02-18
    • 1970-01-01
    相关资源
    最近更新 更多