【问题标题】:An Array of Pointers in CC中的指针数组
【发布时间】:2013-04-26 18:34:03
【问题描述】:

根据以下答案和反映的警告/问题更新了代码

我正在尝试用 C 编写一个指针数组。一个循环设置值,另一个循环检索它们——相当简单。以下是我尝试设置这些值的方式:

static int  *toInvert[8];
for (i=0; i<8; i++)
{
              int *intrplated = //Function call that returns int*
              toInvert[i] = intrplated;
              //printf("OL Value = %d\n\n\n\n\n",oLoop);
}

为了检索值,这里是没有循环的代码,即检索一个固定值:

int *tmpPtr = toInvert[3]; 
printf( "*(TPointer + %d) : %d\n\n", 3, *(toInvert[3] + 1)); //Still gives the recently added value

当我尝试打印这些值时,只会打印setter 循环中最后添加的值。即使我将 tmpPtr 更改为toInvert[1],它仍然会获得最后设置的值。

但如果我在编写的 for 循环中运行相同的代码,它会按预期工作。

我需要知道如何检索所有已设置的值。谢谢

编辑 我想要的是一个包含 8 个指针的 8 个元素的数组。每个指针依次指向一个由 3 个普通整数组成的数组。 我想要的数组应该是[p1][p2]...[p8],其中[p1] 指向一个整数数组。

【问题讨论】:

  • 啊,一个指针数组。如此简单的概念,在 C 语言中却如此复杂。
  • 在 SE 中搜索“[c] 指针数组”时,我得到了 15,966 个结果。 (我试图建议您的问题可能已经在某个地方得到了回答)。
  • 你为什么要取插入变量的地址?
  • 您正在存储一个局部变量的地址,该地址在循环体结束时不再存在。
  • 它甚至不是一个指针数组,它是一个指向指针的数组!

标签: c arrays pointers for-loop


【解决方案1】:

你想要实现的是一个指针数组,对吧?

#include <stdio.h>
#include <stdlib.h>
#define LIMIT 3

int main()
{
    int i,j;
    static int  *toInvert[LIMIT];
    int *intrplated;
    for (i=0; i<LIMIT; i++)
    {
        intrplated = malloc(sizeof(int)*5);
        intrplated[0] = rand();
        intrplated[1] = rand();
        intrplated[2] = rand();
        intrplated[3] = rand();
        intrplated[4] = rand();
        toInvert[i] = intrplated;
    }
    for (i=0;i<LIMIT;i++)
    {
        printf("Tpointer to toInvert[%d] contains::\t [",i);
        for(j=0;j<5;j++)
        {
            printf("%d ",toInvert[i][j]);
        }
        printf("]\n");
    }

    putchar('\n');
    for(j=0;j<5;j++)
    {
        printf("%d ",toInvert[1][j]);
    }
    putchar('\n');
    for(i=0;i<LIMIT;i++)
    {
        free(toInvert[i]);
    }
    return 0;
}

在 GCC 4.8.0 上编译

编辑:查看更改,指针数组保留信息

输出:

Tpointer to toInvert[0] contains::       [41 18467 6334 26500 19169 ]
Tpointer to toInvert[1] contains::       [15724 11478 29358 26962 24464 ] 
Tpointer to toInvert[2] contains::       [5705 28145 23281 16827 9961 ]

15724 11478 29358 26962 24464

【讨论】:

  • 虽然您编写的代码有效,但它仍然会导致我面临的相同问题,即仅检索最后设置的值。例如,如果我打印 toInvert[1][2] ,它将最终打印 toInvert[LIMIT][2]....因为它们是最后设置的那些
【解决方案2】:

你在这里声明了一个指向整数的指针数组:

static int  **toInvert[8];

删除* 以获取指向整数的指针数组。然后在每次迭代时分配intrplated 而不是&amp;intrplatedintrplated 已经是一个指针,所以 &amp;intrplated 是一个指向指针的指针。全部放在一起:

static int *toInvert[8];
for (i=0; i<8; i++)
{
    int *intrplated = //Function call that returns int*
    toInvert[i] = intrplated;
}

【讨论】:

  • 我已经根据您的回答更新了代码,但仍然出现同样的问题 - 除了最后一个值之外,没有检索到任何值
  • @GauravWadhwani 你能确定你正在调用的函数正在为每次调用分配新内存吗?每次调用它时可能会重用相同的内存,在这种情况下,您需要在每次迭代中分配自己的内存,并将 memcpy 值分配到您分配的内存中。
  • 您的意思是返回 int* 的函数调用。那里没有特定于内存的代码,这可能是问题所在。那么如何使用memcpy 调用该函数呢?
  • @GauravWadhwani 如果该函数没有调用malloc,那几乎肯定是问题所在。我会更新我的答案。不过,首先要问一个问题,该函数是否返回指向局部变量的指针(在函数中声明的数组,如int local[3];)?在C 中使用该指针将是未定义的行为,因为在函数返回后数组不存在,在这种情况下需要修复函数本身,而不是调用代码。
  • 该函数有一个声明,如 static int r[4];然后在它的操作之后,它返回 r..
【解决方案3】:

这会起作用。

static int  *toInvert[8];
for (i=0; i<8; i++)
{
          int *intrplated = //Function call that returns int*
          toInvert[i] = intrplated;
          //printf("OL Value = %d\n\n\n\n\n",oLoop);
}

在你的代码中,这个

    static int  **toInvert[8];

表示你有一个指向指针的数组。

这个:

          int *intrplated = //Function call that returns int*
          toInvert[i] = intrplated;

错了。您正在将局部变量 intrplated 的地址传递给您的指针数组。

还有这个

int *tmpPtr = *toInvert[3];
printf( "*(TPointer + %d) : %d\n\n", 3, *(tmpPtr + 1));

也是错误的,由于 toInvert 的错误声明,它可能适用于您的情况,但这是错误的。查找有关混合指针和数组声明的更多信息。

【讨论】:

    【解决方案4】:

    你有太多的*s。

    #include <stdlib.h>
    #include <stdio.h>
    int main() {
    
        static int  *toInvert[8];
        int i;
        for (i=0; i<8; i++)
        {
                  int *intrplated = (int*) calloc(10, sizeof(int));
                  toInvert[i] = intrplated;
                  //printf("OL Value = %d\n\n\n\n\n",oLoop);
        }
    
        int *tmpPtr = toInvert[3];
        printf( "*(TPointer + %d) : %d\n\n", 3, *(tmpPtr + 1));
    
        return 0;
    }
    

    这是一个整数数组:

    int x[8];
    

    这是一个 指针数组 int:

    int *x[8];
    

    【讨论】:

      【解决方案5】:

      您的函数调用可能会覆盖它返回的指针。它应该使用 malloc 分配这个指针,你应该在使用它之后释放它。

      如果函数返回一个指针,你也应该省略 &。

      【讨论】:

        【解决方案6】:

        你不需要 & in:

        toInvert[i] = &intrplated;
        

        正确的做法是:

        toInvert[i] = &intrplated;
        

        由于 intrplate 已经是一个指向整数的指针,因此您获取的是指针的地址而不是指针本身(本质上是指向指针的指针)。

        请记住,指针更像是编译器将其视为内存位置的整数,因此它们本身也存储在某个地方并且也有自己的地址。

        还有这个:

        static int  **toInvert[8];
        

        不是指针的指针,它是指向指针数组的指针。我相信你真正想要的是这样的:

        static int  *toInvert[8];
        

        【讨论】:

          【解决方案7】:

          这段代码:

          for (i=0; i<8; i++)
          {
              toInvert[i] = &intrplated;
          }
          

          toInvert 的每个元素设置为intrplated 的地址。无论您查看toInvert 的哪个元素,您都会取消引用相同的地址并查看存储在intrplated 中的任何值。

          此外,一旦for 循环退出,intrplated 将不再存在,因此在对数组中的值进行引用时会出现未定义的行为。

          如果你想存储函数返回的指针,这就是你需要的。

          for (i=0; i<8; i++)
          {
              toInvert[i] = intrplated;
          }
          

          如果您要存储int *,则需要一个int * 数组,例如:

          int * toInvert[8];
          

          【讨论】:

          • 我确定我需要一个指针数组。
          • “指针数组”或“指针数组”?
          猜你喜欢
          • 1970-01-01
          • 2017-08-25
          • 1970-01-01
          • 1970-01-01
          • 2013-04-19
          • 2010-10-25
          • 1970-01-01
          • 2018-01-04
          • 2013-03-12
          相关资源
          最近更新 更多