将长int转换为void*
Casting a long int to void *
这是将long
强制转换为void *
的正确方法吗?在Qt
程序中使用-O2
时,我遇到了segfault。当使用-O1
时,它不会segfault。
当使用reinterpret_cast<void *>(tp.tv_nsec)
时,我也使用-O2
得到一个segfault。
为什么会出现segfault?
timespec tp; // struct that holds nanoseconds since Epoch
clock_gettime(CLOCK_REALTIME, &tp); // tv_nsec is a long int
void *test = mmap((void *)(tp.tv_nsec), 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
printf("%pn", test);
printf("%lin", (long)test);
编辑:AFAIK,目标似乎表达错误。目标是获得一个随机数,以便分配一个随机存储器地址。这样,每当我在整个测试程序中多次使用mmap()时,我都会得到一个随机内存地址。如果不是,mmap()似乎会按顺序分配内存。
转换无效,因为tp.tv_nsec
不是地址:
mmap((void *)(tp.tv_nsec), 4096,
^
| is not an address
试试这个:
mmap((void *) &(tp.tv_nsec), 4096,
^
| amperson operator for address
&
是(操作数的)地址运算符给出变量的地址
我不想知道为什么要将变量强制转换为地址变量,但您的优化设置之一是反对这一点的:
-O2打开-O指定的所有优化标志。它还打开以下优化标志:
-fthread-jumps
-falign-functions -falign-jumps
-falign-loops -falign-labels
-fcaller-saves
-fcrossjumping
-fcse-follow-jumps -fcse-skip-blocks
-fdelete-null-pointer-checks
-fdevirtualize
-fexpensive-optimizations
-fgcse -fgcse-lm
-fhoist-adjacent-loads
-finline-small-functions ----------> Result: this is causing the segfault(elaine has found so +1 to him please).
-findirect-inlining
-fipa-sra
-foptimize-sibling-calls
-fpartial-inlining
-fpeephole2
-fregmove
-freorder-blocks -freorder-functions
-frerun-cse-after-loop
-fsched-interblock -fsched-spec
-fschedule-insns -fschedule-insns2
-fstrict-aliasing --------> I thought this was issue(void * from long) but is not
-fstrict-overflow
-ftree-switch-conversion -ftree-tail-merge
-ftree-pre
-ftree-vrp
我怀疑:
-fsstrict混叠允许编译器采用适用于正在编译的语言的最严格的别名规则。对于C(和C++),这会激活基于表达式类型的优化。特别是,假设一种类型的对象永远不会与不同类型的对象位于同一地址,除非类型几乎相同。例如,无符号int可以别名为int,但不能别名为void*或double。字符类型可以别名为任何其他类型。
我错了,真丢脸。
>:c
根据elaine的说法,finline小函数是问题的根源
http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
使用构造reinterpret_cast<void *>(tp.tv_nsec)
,您将获取long并将其解释为指针。这导致错误的内存访问。您应该获取其地址并将其强制转换为void*
:reinterpret_cast<void *>(&tp.tv_nsec)
答案是针对C的,但我认为针对C++的答案是类似的。从整数类型到指针的转换并不能保证在所有情况下都有效,因为它们可能具有不同的宽度,并且指针可能会被分段。如果有一个整数类型在您的平台上适用,那么它应该是typedef
到[u]intptr_t
,所以如果您必须执行这种cruft,请使用该类型。
然后,您将mmap
与一些根本无法预见的事情一起使用。如果你给它一个地址,你有责任验证这是你地址空间中的有效地址。例如,它必须是页面大小的倍数,但可能会有其他限制。检查mmap
调用的返回值,看看它是否成功。
首先,最好阅读系统附带的文档。man mmap
是你的朋友。
- Boost buffer_cast 无法从 void* 转换为 PointerToPodType
- 将void*转换为某种类型的shared_ptr
- 如何将 void* 转换为函数指针?
- 对 C++ 中的特定标头使用 extern C 关键字是否允许从 void* 转换为 char*?
- 如何将 void 转换为 typedef void(..)(浮动)
- 无法将参数 1 从"int (__thiscall A::* *)(void)"转换为"int (__cdecl *)(void)"
- 从 'void *' 转换为 'const std::string *&' 必须具有所有中间指针 const 合格
- x = malloc(n * sizeof (int));无法将 void 转换为 int
- 错误:请求从“ void”转换为“ QString”的非量表类型
- 使用 LLVM 从 const void * 转换为模板类型时出现问题
- 如何修复错误:请求从"void"转换为非标量类型"std::vector<int>"
- void* 转换为基类并调用虚函数
- 将 void* 转换为 std::function<void()>
- 无法将参数 4 从 'void' 转换为'const char *'
- C++11 无法将 std::condition_variable::wait 从 'void' 转换为 'bool'
- 如何在 C++11 中将"const void*"转换为函数指针?
- 似乎无法在 c++ 中将 void* 转换为结构
- 将 void 转换为字节
- void * 转换为 int 语法的问题
- C++从类型“void*”转换为类型“double”无效