我编写了一个API,需要初始化上下文,然后传递给每个API调用.调用者为上下文分配内存,然后使用其他参数将其传递给init函数,这些参数描述了他们希望以后的API调用的行为方式.上下文是不透明的,所以客户端不能真正在那里捣乱; 它仅用于API函数的内部使用.
我遇到的问题是调用者正在分配上下文,但没有初始化它.因此,后续API函数指的是无意义的垃圾,就好像它是真实的上下文一样.
我正在寻找一种方法来验证传递给API函数的上下文是否已经初始化.我不确定这是否可行.我想到的两个想法是:
使用预定义的常量并将其存储在上下文的"魔术"字段中,以便在API调用时进行验证.
使用上下文内容的校验和,将其存储在"magic"字段中并在调用时验证它.
不幸的是,我知道这些选项中的任何一个都可能导致误报验证,因为内存中的随机垃圾与"魔术"数字相匹配,或者因为上下文恰好占用了与先前初始化的上下文相同的空间.我认为后一种情况更有可能发生.
这简单归结为概率问题吗?在大多数情况下,我可以避免误报,但不是全部?是否值得使用一个只给我一个合理的准确概率的系统,或者这只会让调试其他问题变得更加困难?
我认为,最佳解决方案是将create()/ delete()函数添加到API中,并使用create来分配和初始化结构.您可以在结构的开头放置一个签名,以验证您传递的指针指向使用create()分配的内存,并在释放内存之前使用delete()覆盖签名(或整个缓冲区).
你实际上无法避免在C中出现误报,因为调用者malloc的内存"发生"从你的签名开始; 但让你的签名合理地长(比如8个字节)并且赔率很低.但是,通过提供create()函数从调用者手中分配将会有很长的路要走.
而且,是的,你最大的风险是在没有使用delete()的情况下释放初始化的缓冲区,并且后续的malloc碰巧重用了那个内存块.