2

这是投射long到的正确方法void *吗?-O2在程序中使用时出现段错误Qt。使用时不会出现段错误-O1

使用时,reinterpret_cast<void *>(tp.tv_nsec)我还使用-O2.

为什么会出现段错误?

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("%p\n", test);
printf("%li\n", (long)test);

编辑: AFAIK,目标似乎表达错误。目标是获取一个随机数以分配一个随机内存地址。这样,每次我在整个测试程序中多次使用 mmap() 时,我都会得到一个随机内存地址。如果没有, mmap() 似乎是按顺序分配内存。

4

4 回答 4

2

强制转换无效,因为tp.tv_nsec不是地址:

mmap((void *)(tp.tv_nsec), 4096,
                 ^ 
                 |  is not an address

尝试这个:

mmap((void *) &(tp.tv_nsec), 4096,
              ^
              |  amperson operator for address

&是地址(操作数)运算符给出变量的地址

于 2013-07-06T13:59:24.313 回答
0

我不知道为什么您将变量转换为地址变量,但您的优化设置之一与此相反:

-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

我怀疑:

-fstrict-aliasing 允许编译器采用适用于正在编译的语言的最严格的别名规则。对于 C(和 C++),这会根据表达式的类型激活优化。特别是,假设一种类型的对象永远不会与不同类型的对象驻留在相同的地址,除非类型几乎相同。例如,unsigned int 可以给 int 起别名,但不能为 void* 或 double。字符类型可以为任何其他类型起别名。

我错了,真丢人。

 >:c

根据 elaine 所说,-finline-small-functions 是问题的根源。

http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

于 2013-07-06T14:01:26.540 回答
0

对于构造reinterpret_cast<void *>(tp.tv_nsec),您需要很长时间并将其解释为指针。这会导致错误的内存访问。您应该获取它的地址并将其转换为void*reinterpret_cast<void *>(&tp.tv_nsec)

于 2013-07-06T13:58:44.810 回答
0

答案是 C,但我想 C++ 是相似的。不能保证从整数类型到指针的转换在所有情况下都有效,因为它们可能具有不同的宽度并且指针可能被分段。如果有一个整数类型适用于您的平台,则应将其typedef编辑为[u]intptr_t,因此如果您必须这样做,请使用该类型。

然后你正在使用mmap一些根本没有预见到会这样做的东西。如果您将地址传递给它,则您有责任验证这是您地址空间中的有效地址以用于该地址。例如,它必须是页面大小的倍数,但其他限制可能适用。检查调用的返回值mmap是否成功。

首先,阅读系统随附的文档可能会很好。man mmap是你的朋友。

于 2013-07-06T14:47:02.893 回答