我喜欢为VS.NET和GCC免费提供代码警告,我喜欢让我的代码准备好64位.
今天我写了一个小模块来处理内存缓冲区,并通过文件样式的接口提供对数据的访问(例如,你可以读取字节,写字节,搜索等).
作为当前读取位置和大小的数据类型,我使用size_t,因为这似乎是最自然的选择.我绕过警告,它也应该在64位工作.
以防万一:我的结构看起来像这样:
typedef struct
{
unsigned char * m_Data;
size_t m_CurrentReadPosition;
size_t m_DataSize;
} MyMemoryFile;
Run Code Online (Sandbox Code Playgroud)
签名size_t似乎没有在实践中定义.Google代码搜索证明了这一点.
现在我处于两难境地:我想检查增加size_t的溢出因为我必须处理用户提供的数据,第三方库将使用我的代码.但是,对于溢出检查,我必须知道符号.它在实施中产生了巨大的差异.
那么 - 我应该如何在平台和编译器独立的方式编写这样的代码?
我可以检查size_t运行或编译时的签名吗?这将解决我的问题.或者也许size_t首先不是最好的主意.
有任何想法吗?
编辑:我正在寻找C语言的解决方案!
一切都在标题中.使用exp()和log()两个函数时如何检查可能的溢出?
从C陷阱和陷阱
如果a和b是两个整数变量,已知是非负的,则测试是否
a+b可能溢出使用:Run Code Online (Sandbox Code Playgroud)if ((int) ((unsigned) a + (unsigned) b) < 0 ) complain();
我没有得到如何比较两个整数与零的总和会让你知道有溢出?
时不时地,特别是当做一些代码库的64位构建时,我注意到有很多情况下整数溢出是可能的.最常见的情况是我做这样的事情:
// Creates a QPixmap out of some block of data; this function comes from library A
QPixmap createFromData( const char *data, unsigned int len );
const std::vector<char> buf = createScreenShot();
return createFromData( &buf[0], buf.size() ); // <-- warning here in 64bit builds
Run Code Online (Sandbox Code Playgroud)
问题是std::vector::size()很好地返回一个size_t(在64位构建中是8个字节)但是该函数恰好采用了unsigned int(在64位构建中仍然只有4个字节).所以编译器会正确警告.
如果可能的话,我会尝试修复签名,以便首先使用正确的类型.但是,当我组合来自不同库的函数时,我经常遇到这个问题,我无法修改.不幸的是,我常常采取一些推理:"好吧,没有人会做截图生成超过4GB的数据,所以为什么要打扰"并且只需更改代码即可
return createFromData( &buf[0], static_cast<unsigned int>( buf.size() ) );
Run Code Online (Sandbox Code Playgroud)
这样编译器就会关闭.然而,这感觉真的很邪恶.所以我一直在考虑使用某种运行时断言,这至少会在调试版本中产生一个很好的错误,如:
assert( buf.size() < std::numeric_limits<unsigned int>::maximum() );
Run Code Online (Sandbox Code Playgroud)
这是一个有点漂亮了,但我想知道:你是怎么处理这种问题,那就是:整数溢出这是"几乎"不可能(实际上).我想这意味着它们不适合你,它们不会出现在QA中 - 但它们会在客户面前爆炸.
可能重复:
在C/C++中检测整数溢出的最佳方法
通常,当我使用大数字在C++中编写某些内容时,我无法判断溢出何时发生,即使我使用的是长long或其他64位数据类型.有没有一种有效的方法来检测何时发生溢出而不是目击错误的值?
可能重复:
在C/C++中检测整数溢出的最佳方法
如果我有一个表达式x + y(在C或C++中)where x和y都是uint64_t导致整数溢出的类型,我如何检测它(进位),位置溢出多少,而不是另一个变量,然后计算余数?
我正在尝试使用errno来检测我是否执行了导致溢出的操作.然而,虽然我写了一个故意溢出的功能,但是errno == ERANGE是假的.这里发生了什么?
这是代码:
#include <stdio.h>
#include <errno.h>
int main(int argc, char* argv[]) {
unsigned char c = 0;
int i;
for (i = 0; i< 300; i++) {
errno = 0;
c = c + 1;
if (errno == ERANGE) {// we have a range error
printf("Overflow. c = %u\n", c);
} else {
printf("No error. c = %u\n", c);
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我预计这会在我们添加1到255的位置发出溢出错误,但没有错误.这是(截断的)输出:
No error. c = 245
No error. c = …Run Code Online (Sandbox Code Playgroud) 可能重复:
检测C / C ++中整数溢出的最佳方法
我正在用C编写函数,但问题是通用的。该函数接受三个整数,并返回有关这三个整数的一些信息。
我怀疑这里的问题是整数可能达到最大值,这可能导致溢出。
例如:如果我尽可能传递a且b可以是1-max,那么在这种情况下,如果条件导致溢出,表达式(a + b)> c会出现吗?如果是这样,我该如何处理?
我的解决方案是保留一个长整数作为临时变量,以保留a + b的值并在表达式中使用它,但这听起来很脏。
请参考以下代码段:
int
triangle_type(int a, int b, int c) {
if (!((a+b)>c)&&((b+c) > a)&&((a+c>b))) {
return -1;
}
}
Run Code Online (Sandbox Code Playgroud) 如果以下任何一项符合标准的方式做"正确的事"?你可以假设m,并n有型int(有符号整数).主要问题是有符号整数溢出.
样品1.
size_t bytes = n * m;
if (n > 0 && m > 0 && SIZE_MAX/n >= m) {
/* allocate “bytes” space */
}
Run Code Online (Sandbox Code Playgroud)
样本2.
if (n > 0 && m > 0 && SIZE_MAX/n >= m) {
size_t bytes = n * m;
/* allocate “bytes” space */
}
Run Code Online (Sandbox Code Playgroud)
样本3.
if (n > 0 && m > 0 && SIZE_MAX/n >= m) {
size_t bytes = (size_t)n * (size_t)m;
/* …Run Code Online (Sandbox Code Playgroud) 我正在学习C++,我试图编写这个函数来找到可以适合整数类型的最大的fibonacci整数:
void findFibThatFitsInAnInt()
{
int n1 = 1;
int n2 = 1;
int fib = 0;
try
{
while ( true )
{
fib = n1 + n2;
n1 = n2;
n2 = fib;
cout << "Fibonacci number : " << fib << "\n";
}
}
catch (overflow_error & e)
{
cout << "The largest fib that can fit into an int is : " << fib << "\n";
cout << e.what() << "\n";
}
cout << "The largest fib …Run Code Online (Sandbox Code Playgroud)