简体   繁体   English

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

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

I am wondering how can I check an array is static or dynamically allocated.我想知道如何检查数组是静态分配还是动态分配。 I looked up online and found the following implementation in mysql source code , I don't know why this works ?我在网上查了一下,在mysql源代码中发现了以下实现,不知道为什么会这样? (line 0303 checks if the array is static) (第 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;

This is the definition of DYNAMIC_ARRAY in mysql :这是 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; 

You can't.你不能。

You're missing some context here.你在这里缺少一些上下文。 In this particular case , it's known that either array->buffer points to (uchar*)(array + 1) and is statically allocated, or it points somewhere else and is dynamically allocated.在这种特殊情况下,众所周知,要么array->buffer指向(uchar*)(array + 1)并静态分配,要么指向其他位置并动态分配。

But there's nothing about (uchar*)(array + 1) that automatically means something is statically allocated.但是(uchar*)(array + 1)没有自动意味着某些东西是静态分配的。

It's like asking how this function finds the length of the array (which is that it doesn't , unless the array ends with a 0):这就像询问这个函数如何找到数组的长度(它不会,除非数组以 0 结尾):

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

You can't - without additional information.你不能 - 没有额外的信息。

For C, an array is just a bunch of memory addresses.对于 C,数组只是一堆内存地址。 a[n] actually means (type(a))*((void*)&a+n*sizeof(a)) . a[n]实际上意味着(type(a))*((void*)&a+n*sizeof(a)) It couldn't care less about how (or if) it was allocated, even whether the addresses are real.它并不关心它是如何(或是否)分配的,即使地址是否真实。

The additional information may be:附加信息可能是:

  • the variable is of a specific type which has fields you can check for the information you want该变量属于特定类型,其中包含您可以检查所需信息的字段
    • this is your case: the code you supplied "knows" the variable is DYNAMIC_ARRAY这是你的情况:你提供的代码“知道”变量是DYNAMIC_ARRAY
  • getting hints from the allocation system从分配系统获取提示
    • eg free and realloc are only supposed to be called with pointers previously given by malloc .例如freerealloc只应该用之前由malloc给出的指针调用。 Checking a pointer's validity, however, isn't a part of the public interface但是,检查指针的有效性不是公共接口的一部分
      • Debugging tools like valgrind , however, typically wrap the functions with a checker to validate the use of the routines然而,像valgrind这样的调试工具通常用检查器包装函数以验证例程的使用

Just to explain what the mysql source code snippet is doing, which may help you.只是为了解释mysql源代码片段在做什么,这可能会对您有所帮助。

Firstly it is not a test for statically allocated arrays.首先,它不是对静态分配数组的测试。 It attempts to test if an array and header were allocated contiguously ( one immediately following the other ).它尝试测试数组和标头是否连续分配(一个紧接另一个)。

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

This is actually taking a pointer to the structure DYNAMIC_ARRAY and checks if the address of the array is pointing to the address immediately after the structure itself.这实际上是获取一个指向结构DYNAMIC_ARRAY的指针,并检查数组的地址是否指向紧跟在结构本身之后的地址。

One way the test will be true is if the structure and array space were allocate in one single malloc() - a contiguous block.测试为真的一种方式是结构和数组空间是否在单个 malloc() 中分配 - 一个连续块。 For example :例如 :

DYNAMIC_ARRAY *dap = NULL ;

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

This, IMO, is an unsafe piece of code, as it makes a dangerous assumption. IMO,这是一段不安全的代码,因为它做出了危险的假设。

It assumes that two separate allocations, one of a header structure and one of array space, cannot follow each other in memory.它假设两个单独的分配,一个是头结构,一个是数组空间,不能在内存中相互跟随。 This is outside of the control of the application, unless they've explicitly coded their own memory manager to not do that.这超出了应用程序的控制范围,除非他们明确地编写了自己的内存管理器来避免这样做。

If this trick is being used elsewhere in the mysql sources I'd be quite alarmed, as it's just asking for trouble.如果这个技巧在 mysql 源代码的其他地方被使用,我会非常震惊,因为它只是在自找麻烦。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM