可以使用OpenCV Error: The function/feature is not implemented () in CvStatModel::write, file ..\..\..\modules\ml\src\inner_functions.cpp
安全地在C中分配大小为x
的{{1}}元素,而y
会处理乘法calloc(x, y)
。
但是calloc()
例如只将新大小作为参数,我想知道如何使用x*y
安全地重新分配realloc()
个字节。
如果x*y
不适合realloc()
,该怎么办? x*y
如何处理这个问题?
答案 0 :(得分:4)
size_t
是无符号类型,size_t
的最大值是可以使用realloc
或malloc
分配的对象的绝对最大大小;这可以在宏SIZE_MAX
中找到。在32位个人计算机上,size_t
通常是32位; 64位计算机上的64位。这应该足够了。
为确保item_size * n_items
的计算不会溢出,您可以将SIZE_MAX
除以item_size
并确保结果值大于或等于n_items
:
size_t max_items = SIZE_MAX / item_size;
if (max_items < n_items) {
// an overflow would occur
}
else {
// it is ok
}
如果分配失败, calloc
必须返回NULL
,因此calloc
最有可能检查类似于上面的那个。
答案 1 :(得分:1)
简短的回答是你无法安全地做到这一点。您可以做的最多是限制尝试分配的内存量,使其不超过SIZE_MAX
。
SIZE_MAX
是sizeof
运算符可以生成的最大值。
C中的每种数据类型都必须具有可以使用sizeof
计算的大小,包括数组,以及使用malloc()
,calloc()
或{{1}分配的任何连续内存块}}
如果realloc()
在数学上大于x*y
,那么无法以任何方式分配该数量的内存。即使底层系统支持,C程序也无法完全使用该内存块。
还有一个问题是,计算SIZE_MAX
(假设x*y
和x
的类型为y
)将使用模运算,因此实际上会给结果在数学上等效到size_t
。
答案 2 :(得分:1)
如果x * y不适合size_t怎么办?
calloc()
如何处理这个问题?
realloc()
和malloc()
受到限制,因为传递给它们的size参数仅限于SIZE_MAX
。 calloc()
符合要求的C实现不要求calloc()
限制仅分配SIZE_MAX
的内存。以下可能有效。单个类型的最大大小为SIZE_MAX
,数组大小可以与SIZE_MAX
SIZE_MAX-1 “bytes”一样大,但下面的iptr
不是数组,而是指针。
// Assume sizeof(double) == 8
double *iptr = calloc(SIZE_MAX, sizeof *iptr);
重新分配如此大的指针是有问题的,因为它需要使用另一个调用calloc()
如何避免
realloc
溢出?
OP的问题不在于realloc()
可以处理的问题,而在于代码如何计算传递给它的值可能会溢出。
确保无符号类型(如size_t
)不会溢出乘法:
if (b && a > SIZE_MAX/b) Handle_Overflow();
prod = a*b;
答案 3 :(得分:0)
size_t
是无符号类型。
对于无符号类型,溢出行为是确定性的,如C11
[....]因为无法用结果无符号整数类型表示的结果是 减少模数可以是最大值的数字 由结果类型表示。
因此,只要确保生成要存储在变量类型size_t
中的值的操作在进程中没有溢出,将该变量传递给realloc()
就不会产生任何影响。最多,realloc()
将无法分配该内存。
答案 4 :(得分:0)
如果x * y
溢出size_t
,realloc将尝试分配溢出的值:
bytes = (x * y) % 2^(sizeof(size_t) * 8)
因此realloc
将“看到”bytes
个字节数。它没有照顾任何事情。