有没有办法检查是否在堆栈/堆上创建了可变长度数组?

时间:2017-01-18 04:44:38

标签: c arrays c99

据我所知,以下代码生成可变长度数组(通过C ++的非标准扩展)。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">

<ImageView
    android:layout_width="110dp"
    android:layout_height="match_parent" />

<RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="match_parent">

    <View
        android:id="@+id/B"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_alignParentTop="true"
        android:minHeight="50dp">

    </View>

    <View
        android:id="@+id/D"
        android:layout_width="60dp"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentRight="true"
        android:layout_below="@id/B" />

    <View
        android:id="@+id/C"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/B"
        android:layout_toLeftOf="@id/D" />

    </RelativeLayout>

</LinearLayout>

有没有办法检查它是在堆栈还是堆上生成的?维基百科描述here表示int main() { int valone = rand(); int valtwo = rand(); int array[valone][valtwo]; // Printing size cout << sizeof(array) << endl; } 在堆栈中生成相同的内容,但是当我尝试上面的代码时,大多数情况下,数组大小似乎太大而无法放入堆栈,但它从不会抱怨。 / p>

注意:此代码仅适用于gcc&amp;铿锵而不是视觉工作室

3 个答案:

答案 0 :(得分:1)

这可能是一个棘手的问题,我尝试过像

这样的事情
#include "iostream"

int Stack_or_heap(void* ptr)
{
 int dummy;
 return ptr > &dummy;
}

int main(int argc, char** argv)
{
   int* i = new int();
   int x, y, z;
   std::cout << Stack_or_heap(&x) << Stack_or_heap(&y) << Stack_or_heap(&z) << Stack_or_heap(i);
}

答案 1 :(得分:1)

  

数组大小似乎太大而无法放入堆栈,但它永远不会抱怨。

从不抱怨&#34;,我认为你的意思是程序不会崩溃。

你永远不会触摸你分配的内存,编译器足够聪明,可以证明它并没有分配任何东西。

让我们获取变量的地址,并将其发送到其他地方定义的函数:

int array[valone][valtwo] = {};
cout << &array << endl;

现在,编译器并不十分确定永远不会访问该数组。这是因为它无法进入另一个翻译单元中实现的流媒体运营商。也许操作员会取消引用指针;我们必须确保数组存在。

Segfault在我第一次尝试时崩溃了这个程序。堆栈溢出。

我认为这种碰撞测试是一种测试VLA是否在堆栈中的方法。

Mikhail在评论中建议将自动变量的邻接与VLA进行比较,这是一个不错的平台依赖理念,但它只有在你分配足够小的VLA并且不会使程序崩溃时才能起作用。 / p>

答案 2 :(得分:0)

首先,我假设您知道使用malloc或new在堆中分配的任何内存块在整个程序中都会延续其生命周期,除非显式释放。因此,我们可以得出结论,如果变量长度数组仅存在于其范围内但不存在于程序的生命周期中,则很可能在堆栈中分配。

我不知道是否存在堆中分配内存的情况,但其行为就好像它是堆栈的成员一样。最好看看汇编代码。这样的实现可能会使用动态分配函数/系统调用。

如果看起来像鸭子,像鸭子一样走路,像鸭子一样说话,那么假设它是鸭子(大部分时间)应该是安全的。