【问题标题】:Unable to return a 3d array from function through pointers无法通过指针从函数返回 3d 数组
【发布时间】:2014-07-06 20:06:48
【问题描述】:

我有一个函数,它返回一个 3-d 整数数组作为指向其中第 0 个 2-D 数组的第 0 个 1-D 数组的指针。它的尺寸为2*3*4。这是我的功能:

    int (*ultimate())[4] {
        int a[2][3][4] = {
                {
                        {1,2,3,4},
                        {5,6,7,8},
                        {9,10,11,12}
                },
                {
                        {13,14,15,16},
                        {17,18,19,20},
                        {21,22,23,24}
                }
        };
        return (int (*)[4]) a;
    }

我以两种不同的方式使用此功能:

在第一种方法中,我将指针指向一维数组,看到有 6 个这样的数组,逐个打印出来:

int (*q)[4];
q = ultimate();
for (int i = 0; i < 2*3; i++) {
    printf("\n");
    for (int k = 0; k < 4; k++) {
        printf("%d ",*(*(q+i)+k));
    }
}

在下一个方法中,我只是简单地使用返回值来获取3-D数组中第一个元素的地址,然后打印全部:

int *p;
    for (int i = 0; i < 2; i++) {
        p = (int *) (q+i*3);
        pnl();
        for (int j = 0; j < 3; j++) {
            for (int k = 0; k < 4; k++) {
                printf("%d",*p);
                p++;
            }
        }
    }

但是,在这两种情况下,我都会得到垃圾值。在第一种方法中,我得到了数组的一些行,而其他值是垃圾,而在第二种方法中,所有值都是垃圾。知道我哪里错了吗?

【问题讨论】:

  • 你可以写q[i][k],而不是*(*(q+i)+k))。 (IDK 其他人如何发现您的版本更具可读性)

标签: c arrays pointers multidimensional-array


【解决方案1】:

您正在堆栈上的函数内部创建数组。当函数退出时,该内存被回收。因此无法保证您将能够访问这些值。

您获得随机正确值的原因是偶然的,该内存区域尚未被覆盖。为避免这种情况,请使用malloc 在堆上声明数组或创建静态常量等。


编辑:静态常量是指函数外部的全局常量。从技术上讲,函数内静态变量的生命周期等于程序的生命周期。但是因为 C 规范不保证线程安全,所以在程序关闭时可能会出现潜在的错误。

编辑 2:我设法找到了一个描述此问题的 SO 问题:What is the lifetime of a static variable in a C++ function?

【讨论】:

  • 谢谢!我应该将数组声明为静态的!现在它对两者都适用,正如预期的那样。
  • 而且我没有返回数组类型,对吧?我正在返回一个指针,该指针已被适当地转换。为什么错了?
  • 你在哪里声明它是静态的?不要在函数内部这样做 - 仍然会失败。
  • 在里面声明静态可能会失败?怎么会?
  • @metacubed 返回int*** 在这里是不可能的。没有指针指向。他的代码返回一个指向int[4] 的指针,这是正确的(尽管 IMO 风格很差)
【解决方案2】:

在 C/C++ 中,函数不能将数组声明为返回类型。

例如在C标准中有这样写

6.7.6.3 函数声明符(包括原型) 约束 1 函数声明器不应指定返回类型为函数类型或数组 输入。

至于您的代码,它具有未定义的行为,因为该函数返回指向具有数组类型的本地对象的指针。退出函数后,数组将被销毁。

【讨论】:

  • 嗯,没错。这就是为什么我返回一个指向子数组的指针,如果你再次看到我的问题..
猜你喜欢
  • 2021-11-17
  • 2018-01-10
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多