【发布时间】:2021-03-16 16:03:09
【问题描述】:
假设我们有一个由 C++ 库公开的 C API,其中 C 客户端通过传递 void 指针和键来查询值。
bool GetValue(const char* key, void* val) {
if(val != NULL) {
// find the value using the key with some logic of library
// lets assume found value is a int
int foundValue = 34;
*(int*)val = foundValue;
return true; // or false if key not found
}
return false;
}
C 客户端和 C++ 库开发人员就与键关联的值的大小达成一致。
假设C++库只有int和long long int,C客户端也知道。
因此,当与"some_key" 关联的值为int 时,C 客户端的行为预计如下:
int valueHolder;
if(GetValue("some_key",&valueHolder)) {
// do something with valueHolder
}
但是 C 客户端可以通过提供指向较少空间的指针来导致堆栈内存损坏。例如,如果 C 客户端提供了一个指向 unsigned char 的指针,而 C++ 库写入的值为 int,则可能会发生堆栈内存损坏。
所以 C 客户端应该采取适当的措施来避免这种情况。我的问题是,C++ 库如何处理这种内存损坏/崩溃情况以及如何应对崩溃或内存损坏? (一个小提示:模板或函数重载对我来说不是一个选项,因为 C++ 库无法将此类功能公开给 C 客户端)。
【问题讨论】:
-
GetValue对val指向的类型一无所知。所以你无能为力。可能你应该放弃void *val并为不同的类型提供不同的功能。例如。GetValueInt(const char* key, int* val)和GetValueLongLöongInt(const char* key, long long int* val)等。也许这是一个 XY Problem。 -
能否更改 API 以在指针中添加“缓冲区大小”参数?
-
C 和 C++ 都不是内存安全语言。它赋予开发者更多的权力和更多的责任。
-
@Jabberwocky。
have different functions for different types看起来像是最后的手段。我们实际上试图避免为所有类型编写函数,但最终出现了这种情况。 -
@Debashish 当然是的,没有人声称 C++ 和 C 是安全语言。