C / C ++:如何在运行时检查数组是静态的还是动态的

时间:2015-12-23 03:17:03

标签: c++ c arrays runtime

我想知道如何检查数组是静态的还是动态分配的。我在网上查了一下,在mysql source code找到了以下实现,我不知道为什么会这样? (第0303行检查数组是否为静态)

       /*

0301     Just mark as empty if we are using a static buffer
0302   */
0303   if (array->buffer == (uchar *)(array + 1))
0304     array->elements= 0;

这是mysql中DYNAMIC_ARRAY的定义:

341  
342 typedef struct st_dynamic_array
343 { 
344     uchar *buffer; 
345     uint elements,max_element; 
346     uint alloc_increment; 
347     uint size_of_element; 
348 } DYNAMIC_ARRAY; 

3 个答案:

答案 0 :(得分:3)

你不能。

你在这里错过了一些背景。 在此特定情况中,已知array->buffer指向(uchar*)(array + 1)并且已静态分配,指向其他地方并且动态分配。

(uchar*)(array + 1)没有任何内容可以自动表示某些内容是静态分配的。

这就像询问这个函数如何找到数组的长度一样(除非数组以0结尾,否则它不会):

int getArrayLength(int *a)
{
    for(int i = 0; ; i++)
        if(a[i] == 0)
            return i + 1;
}

答案 1 :(得分:1)

您无法提供其他信息。

对于C,数组只是一堆内存地址。 a[n]实际上意味着(type(a))*((void*)&a+n*sizeof(a))。即使地址是否真实,它也不会关心如何(或如果)分配它。

附加信息可能是:

  • 该变量属于特定类型,其中包含可以检查所需信息的字段
    • 这是你的情况:你提供的代码"知道"变量是DYNAMIC_ARRAY
  • 从分配系统中获取提示
    • e.g。 freerealloc仅应使用先前由malloc指定的指针进行调用。但是,检查指针的有效性并不是公共接口的一部分
      • 调试工具如valgrind,但通常使用检查器包装函数以验证例程的使用

答案 2 :(得分:0)

只是为了解释mysql源代码片段正在做什么,这可能会对你有帮助。

首先,对静态分配的数组进行测试。它试图测试是否连续分配了一个数组和头(一个紧接着另一个)。

if (array->buffer == (uchar *)(array + 1))
    array->elements= 0;

这实际上是一个指向结构DYNAMIC_ARRAY的指针,并检查数组的地址是否指向结构本身后面的地址。

测试的一种方法是,如果结构和数组空间是在一个malloc()中分配的 - 一个连续的块。例如:

DYNAMIC_ARRAY *dap = NULL ;

dap = malloc( sizeof(DYNAMIC_ARRAY) + arraylength ) ;
dap->buffer = (uchar *)(dap+1) ;

IMO这是一段不安全的代码,因为它是一个危险的假设。

它假定两个单独的分配,一个是头结构,另一个是数组空间,在内存中不能互相跟随。这超出了应用程序的控制范围,除非他们明确地将自己的内存管理器编码为不执行此操作。

如果在mysql源代码的其他地方使用这个技巧,我会非常惊慌,因为它只是在寻找麻烦。