将一个长整数转换为void *。

时间:2022-02-22 04:58:20

Is this the correct way of casting a long to void *? I'm getting a segfault when using -O2 in a Qt program. It does not segfault when using -O1.

这是正确的方式投长空*?在Qt程序中使用-O2时,我得到了一个segfault。在使用-O1时,它不分段。

When using reinterpret_cast<void *>(tp.tv_nsec) I also get a segfault using -O2.

当使用reinterpret_cast (tp.tv_nsec)时,我也使用-O2获得segfault。

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

EDIT: AFAIK, the objective seems to have been expressed wrong. The objective is to get a random number in order to allocate a random memory address. That way I will get a random memory address every time I feed mmap() a random number the many times I use mmap() throughout my test program. If not, mmap() seems to allocate memory rather sequentially.

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

4 个解决方案

#1


0  

I am not wondering why you cast a variable into an address variable but one of your optimization settings are against this:

我不奇怪为什么你把一个变量转换成一个地址变量,但是你的一个优化设置是反对的:

-O2 turns on all optimization flags specified by -O. It also turns on the following optimization flags:

-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

I suspected:

我怀疑:

-fstrict-aliasing Allow the compiler to assume the strictest aliasing rules applicable to the language being compiled. For C (and C++), this activates optimizations based on the type of expressions. In particular, an object of one type is assumed never to reside at the same address as an object of a different type, unless the types are almost the same. For example, an unsigned int can alias an int, but not a void* or a double. A character type may alias any other type.

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

I was wrong, shame on me.

我错了,我真惭愧。

 >:c

According to what elaine said, -finline-small-functions is source of the problem.

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

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

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

#2


2  

casting is not valid because tp.tv_nsec is not an address:

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

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

Try this:

试试这个:

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

& is Address (of operand) operator gives address of a variable

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

#3


0  

With construction reinterpret_cast<void *>(tp.tv_nsec) you are taking long and interpret it as a pointer. This cause to wrong memory access. You should take its address and cast it into void*: reinterpret_cast<void *>(&tp.tv_nsec)

有了结构reinterpret_cast (tp.tv_nsec),你就把它当成一个指针。这会导致错误的内存访问。您应该获取它的地址并将其转换为void*: reinterpret_cast (&tp.tv_nsec)

#4


0  

Answer is for C, but I suppose that for C++ is similar. Conversion from integer types to pointer is not guaranteed to work in all cases, since they may have different width and pointers may be segmented. If there is an integer type for which this works on your platform, it should be typedefed to [u]intptr_t, so if you have to do such cruft, use that type.

答案是C,但我认为c++也是类似的。从整数类型到指针的转换不能保证在所有情况下都有效,因为它们可能有不同的宽度,指针可以被分割。如果在您的平台上有一个整数类型,那么它应该被类型化为[u]intptr_t,因此如果您必须执行这种cruft,请使用该类型。

Then you are using mmap with something that is not at all foreseen to be done like that. If you pass it an address it is your duty to verify that this is a valid address in your address space to use for that. E.g it must be a multiple of a page size, but other restrictions may apply. Check the return value of the mmap call to see if it succeeded.

然后你用mmap来做一些根本没有预见到的事情。如果你给它一个地址,你有责任验证这是一个有效的地址在你的地址空间使用。E。它必须是一个页面大小的倍数,但也可以应用其他限制。检查mmap调用的返回值,看看它是否成功。

For a start it would probably be good to read the documentation that comes with your system. man mmap is your friend.

首先,最好阅读系统附带的文档。人地图是你的朋友。

#1


0  

I am not wondering why you cast a variable into an address variable but one of your optimization settings are against this:

我不奇怪为什么你把一个变量转换成一个地址变量,但是你的一个优化设置是反对的:

-O2 turns on all optimization flags specified by -O. It also turns on the following optimization flags:

-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

I suspected:

我怀疑:

-fstrict-aliasing Allow the compiler to assume the strictest aliasing rules applicable to the language being compiled. For C (and C++), this activates optimizations based on the type of expressions. In particular, an object of one type is assumed never to reside at the same address as an object of a different type, unless the types are almost the same. For example, an unsigned int can alias an int, but not a void* or a double. A character type may alias any other type.

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

I was wrong, shame on me.

我错了,我真惭愧。

 >:c

According to what elaine said, -finline-small-functions is source of the problem.

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

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

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

#2


2  

casting is not valid because tp.tv_nsec is not an address:

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

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

Try this:

试试这个:

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

& is Address (of operand) operator gives address of a variable

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

#3


0  

With construction reinterpret_cast<void *>(tp.tv_nsec) you are taking long and interpret it as a pointer. This cause to wrong memory access. You should take its address and cast it into void*: reinterpret_cast<void *>(&tp.tv_nsec)

有了结构reinterpret_cast (tp.tv_nsec),你就把它当成一个指针。这会导致错误的内存访问。您应该获取它的地址并将其转换为void*: reinterpret_cast (&tp.tv_nsec)

#4


0  

Answer is for C, but I suppose that for C++ is similar. Conversion from integer types to pointer is not guaranteed to work in all cases, since they may have different width and pointers may be segmented. If there is an integer type for which this works on your platform, it should be typedefed to [u]intptr_t, so if you have to do such cruft, use that type.

答案是C,但我认为c++也是类似的。从整数类型到指针的转换不能保证在所有情况下都有效,因为它们可能有不同的宽度,指针可以被分割。如果在您的平台上有一个整数类型,那么它应该被类型化为[u]intptr_t,因此如果您必须执行这种cruft,请使用该类型。

Then you are using mmap with something that is not at all foreseen to be done like that. If you pass it an address it is your duty to verify that this is a valid address in your address space to use for that. E.g it must be a multiple of a page size, but other restrictions may apply. Check the return value of the mmap call to see if it succeeded.

然后你用mmap来做一些根本没有预见到的事情。如果你给它一个地址,你有责任验证这是一个有效的地址在你的地址空间使用。E。它必须是一个页面大小的倍数,但也可以应用其他限制。检查mmap调用的返回值,看看它是否成功。

For a start it would probably be good to read the documentation that comes with your system. man mmap is your friend.

首先,最好阅读系统附带的文档。人地图是你的朋友。