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

C/C++: How to check if an array is static or dynamic during runtime

本文关键字:数组 动态 静态 检查 运行时 C++      更新时间:2023-10-16

我想知道如何检查数组是静态的还是动态分配的。我在网上查找并在mysql源代码中找到了以下实现,我不知道为什么可以工作?(第 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; 

你不能。

您在此处缺少一些上下文。在这种特殊情况下,已知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;
}
你不能

- 没有额外的信息。

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

附加信息可能是:

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

只是为了解释 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 源代码的其他地方使用,我会非常震惊,因为它只是在自找麻烦。