BCS*_*BCS 0 c++ low-level segmentation-fault
以下使用seg-V崩溃:
// my code
int* ipt;
int bool set = false;
void Set(int* i) {
ASSERT(i);
ipt = i;
set = true;
}
int Get() {
return set ? *ipt : 0;
}
// code that I don't control.
struct S { int I, int J; }
int main() {
S* ip = NULL;
// code that, as a bug, forgets to set ip...
Set(&ip->J);
// gobs of code
return Get();
}
Run Code Online (Sandbox Code Playgroud)
这是因为虽然i它不是NULL仍然无效.如果调用代码从NULL指针获取数组索引操作的地址,则会发生同样的问题.
对此的一个解决方案是修剪低阶位:
void Set(int* i) {
ASSERT((reinterpret_cast<size_t>(i))>>10);
ipt = i;
set = true;
}
Run Code Online (Sandbox Code Playgroud)
但是我应该/可以摆脱多少位?
编辑,我并不担心未定义的行为,因为无论如何我都会中止(但比seg-v更干净).
FWIW:这是一个半假设的情况.在我发布之前,导致我想到这个问题的错误已得到解决,但我之前遇到过它并且正在考虑将来如何使用它.
为了论证可以假设的事情:
Mik*_*our 12
除了NULL之外,没有可移植的方法来测试任何无效指针.&ip[3]在对它做任何事情之前,评估会给出未定义的行为; 唯一的解决方案是在对指针进行任何算术之前测试NULL .
如果您不需要可移植性,并且不需要保证捕获所有错误,那么在大多数主流平台上,您可以检查地址是否在内存的第一页内; 通常将NULL定义为地址零,并保留第一页以捕获大多数空指针解引用.在POSIX平台上,这看起来像
static size_t page_size = sysconf(_SC_PAGESIZE);
assert(reinterpret_cast<intptr_t>(i) >= page_size);
Run Code Online (Sandbox Code Playgroud)
但这不是一个完整的解决方案.唯一真正的解决方案是首先解决滥用空指针的问题.
| 归档时间: |
|
| 查看次数: |
299 次 |
| 最近记录: |