I have a method that returns void* and it is basically some block of data from allocated shared memory on linux.
The first 4 bytes in that data are an int and I haven't managed to extract that int.
These are the methods what I have tried:
int getNum(void* data)
{
return *(int*)data; // 1
return *(int*)(data & 0xFFFFFFFF); // 2
}
Thanks in advance!
int getNum(void* data)
{
return *(int32_t*)data; // 1
// ^^^^^^^
}
Should work.
Also if you need to worry about unaligned addresses achieved from the void*, you may use #Martin Bonner's suggestion:
int getNum(void* data)
{
int32_t result;
memcpy(&result, data, sizeof(int32_t));
return result;
}
int getNum(void* data)
{
return *(int*)data; // 1
return *(int*)(data & 0xFFFFFFFF); // 2
}
The second method won't even compile; data is a pointer, and you cannot apply the & bitwise and operator to a pointer value. (I don't know why you'd even want to mask a pointer value like that. If it were legal, the mask would do nothing on a 32-bit system, and would probably destroy the pointer value on a 64-bit system.)
As for the first, it should work -- if data is a valid pointer pointing to a properly aligned int object.
If that's failing at run time with a segmentation fault, it probably means either that data is null or otherwise not a valid pointer (in that case you can't do what you're trying to do), or it points to a misaligned address (which won't cause a seg fault if you're on an x86 or x86_64 system; are you?).
To find out what the pointer looks like, try adding this:
printf("data = %p\n", data);
to your getNum function -- or examine the value of data in a debugger.
If alignment is the problem, then you can do this:
int result;
memcpy(&result, data, sizeof result);
return result;
But in that case storing an int value as a misaligned address is an odd thing to do in the first place. It's not necessarily wrong, just a very odd thing to do.
How is the memory that data points to allocated?
Assuming the int is 4 bytes long, and you're operating on Linux, your method will work. If you want a portable method to move ints in pointers, try the open source ptrint module from CCAN. It converts a pointer to int by adding NULL to the int. It converts in the other direction by subtracting NULL, returning a ptrdiff_t.
#include <assert.h>
#include <stdio.h>
int getNum(void* data)
{
return *(int *) data;
}
char buf[16];
int main(void)
{
assert(sizeof(int) == 4);
*(int *)buf = 9;
printf("%c%c%c%c\n", buf[0], buf[1], buf[2], buf[3]);
printf("%d\n", getNum((void *) buf));
return 0;
}
// $ ./foo | cat -tv
// ^I^#^#^#
// 9
Related
Is there a portable way to implement a tagged pointer in C/C++, like some documented macros that work across platforms and compilers? Or when you tag your pointers you are at your own peril? If such helper functions/macros exist, are they part of any standard or just are available as open source libraries?
Just for those who do not know what tagged pointer is but are interested, it is a way to store some extra data inside a normal pointer, because on most architectures some bits in pointers are always 0 or 1, so you keep your flags/types/hints in those extra bits, and just erase them right before you want to use pointer to dereference some actual value.
const int gc_flag = 1;
const int flag_mask = 7; // aka 0b00000000000111, because on some theoretical CPU under some arbitrary OS compiled with some random compiler and using some particular malloc last three bits are always zero in pointers.
struct value {
void *data;
};
struct value val;
val.data = &data | gc_flag;
int data = *(int*)(val.data & flag_mask);
https://en.wikipedia.org/wiki/Pointer_tagging
You can get the lowest N bits of an address for your personal use by guaranteeing that the objects are aligned to multiples of 1 << N. This can be achieved platform-independently by different ways (alignas and aligned_storage for stack-based objects or std::aligned_alloc for dynamic objects), depending on what you want to achieve:
struct Data { ... };
alignas(1 << 4) Data d; // 4-bits, 16-byte alignment
assert(reinterpret_cast<std::uintptr_t>(&d) % 16 == 0);
// dynamic (preferably with a unique_ptr or alike)
void* ptr = std::aligned_alloc(1 << 4, sizeof(Data));
auto obj = new (ptr) Data;
...
obj->~Data();
std::free(ptr);
You pay by throwing away a lot of memory, exponentionally growing with the number of bits required. Also, if you plan to allocate many of such objects contiguously, such an array won't fit in the processor's cacheline for comparatively small arrays, possibly slowing down the program considerably. This solution therefore is not to scale.
If you're sure that the addresses you are passing around always have certain bits unused, then you could use uintptr_t as a transport type. This is an integer type that maps to pointers in the expected way (and will fail to exist on an obscure platform that offers no such possible map).
There aren't any standard macros but you can roll your own easily enough. The code (sans macros) might look like:
void T_func(uintptr_t t)
{
uint8_t tag = (t & 7);
T *ptr = (T *)(t & ~(uintptr_t)7);
// ...
}
int main()
{
T *ptr = new T;
assert( ((uintptr_t)ptr % 8) == 0 );
T_func( (uintptr_t)ptr + 3 );
}
This may defeat compiler optimizations that involve tracking pointer usage.
Well, GCC at least can compute the size of bit-fields, so you can get portability across platforms (I don't have an MSVC available to test with). You can use this to pack the pointer and tag into an intptr_t, and intptr_t is guaranteed to be able to hold a pointer.
#include <limits.h>
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <inttypes.h>
struct tagged_ptr
{
intptr_t ptr : (sizeof(intptr_t)*CHAR_BIT-3);
intptr_t tag : 3;
};
int main(int argc, char *argv[])
{
struct tagged_ptr p;
p.tag = 3;
p.ptr = (intptr_t)argv[0];
printf("sizeof(p): %zu <---WTF MinGW!\n", sizeof p);
printf("sizeof(p): %lu\n", (unsigned long int)sizeof p);
printf("sizeof(void *): %u\n", (unsigned int)sizeof (void *));
printf("argv[0]: %p\n", argv[0]);
printf("p.tag: %" PRIxPTR "\n", p.tag);
printf("p.ptr: %" PRIxPTR "\n", p.ptr);
printf("(void *)*(intptr_t*)&p: %p\n", (void *)*(intptr_t *)&p);
}
Gives:
$ ./tag.exe
sizeof(p): zu <---WTF MinGW!
sizeof(p): 8
sizeof(void *): 8
argv[0]: 00000000007613B0
p.tag: 3
p.ptr: 7613b0
(void *)*(intptr_t*)&p: 60000000007613B0
I've put the tag at the top, but changing the order of the struct would put it at the bottom. Then shifting the pointer-to-be-stored right by 3 would implement the OP's use case. Probably make macros for access to make it easier.
I also kinda like the struct because you can't accidentally dereference it as if it were a plain pointer.
I'm attempting to display the contents of a specific address, given a char* to that address. So far I had attempted doing it using the following implementation
int mem_display(char *arguments) {
int address = *arguments;
int* contents_pointer = (int*)address;
int contents = *contents_pointer;
printf("Address %p: contents %16x\n", contents_pointer, contents);
}
But I keep getting a "Segmentation Fault (Core Dumped)" error. I attempted to make a dummy pointer to test on
char foo = 6;
char *bar = &foo;
But the error still persists
I'm finding it hard to explain what the problem is because almost every single line in your code is wrong.
Here's what I would do:
void mem_display(const void *address) {
const unsigned char *p = address;
for (size_t i = 0; i < 16; i++) {
printf("%02hhx", p[i]);
}
putchar('\n');
}
You need to iterate over the contents of the address, and print each one separately, until you reach 16. Example code:
#include <stdio.h>
void mem_display(unsigned char *arguments) {
printf("Address %p: ", arguments);
int i =0;
unsigned char* byte_array = arguments;
while (i < 16)
{
printf("%02hhx", byte_array[i]);
i++;
}
}
int main(void) {
unsigned char foo = 6;
unsigned char *bar = &foo;
mem_display(bar);
return 0;
}
Output:
Address 0x7ffe5b86a777: 0677A7865BFE7F000060054000000000
If you already have a pointer to the address you want to print the contents of, you can feed that straight to printf, like this:
void print_16_bytes_at(const char *arguments)
{
printf("Address %p: contents", (const void *)arguments);
for (int i = 0; i < 16; i++)
printf(" %02x", (unsigned int)(unsigned char)arguments[i]);
putchar('\n');
}
If arguments isn't a pointer to the memory you want to print the contents of, then I don't understand what it actually is and I need you to explain better.
Notes on the above sample code:
To use %p without provoking undefined behavior, you must explicitly cast the pointer to [const] void * unless it is already [const] void *. Because printf takes a variable number of arguments, the compiler does not know the expected types of its arguments, so it doesn't insert this conversion for you, as it would with a normal function that takes a [const] void * argument.
The double cast (unsigned int)(unsigned char) forces the char read from arguments[i] to be zero-extended rather than sign-extended to the width of unsigned int. If you don't do that, values from 0x80 on up are liable to be printed with a bunch of leading Fs (e.g. ffffff80) which is probably not what you want.
This will still segfault if there aren't 16 bytes of readable memory at the supplied address. In your example
char foo = 6;
print_16_bytes_at(&foo);
there is only guaranteed to be one byte of readable memory at the address of foo. (It will probably work on any computer you can readily get at, but it's still allowed to crash per the letter of the C standard.)
There are a few issues with the original code. First, it is indirecting the passed in pointer twice. It is treating arguments as a pointer to a pointer to the contents to be printed. Since arguments is a pointer to char, this is definitely wrong. (It will end up reading from a very small address, which is a definite segmentation violation or other crash on most architectures.)
Second, unless you know the arguments pointer is aligned appropriately, loading an int via that pointer may crash due to an unaligned access. (Which may well show up as a segmentation violation.) You likely cannot assume proper alignment for this routine.
Third, if you need to print 16 bytes, then an int will (typically) only get 4 or 8 of them. It will be trickier to use standard printing routines to concatenate all the pieces than to write a byte by byte loop. (See above answer for an example of such a loop.)
I think you are either overcomplicating it, or you didn't describe enough what is the actual input. Is it pointer to pointer?
Anyway, to do it in simple way with some pointer to memory, you can do it like this for example (C-like C++, sorry, done in hurry online at web cpp.sh ):
#include <iostream>
const unsigned char fakeData[] = { 1, 13, 0, 255 };
void mem_display(
std::FILE* file,
const unsigned char* memoryPtr,
const size_t size)
{
fprintf(file, "Address %p:", (const void*)memoryPtr);
for (size_t i = 0; i < size; ++i) fprintf(file, " %02hhx", memoryPtr[i]);
fprintf(file, "\n");
}
int main()
{
mem_display(stdout, fakeData, 4);
}
Output:
Address 0x4008e6: 01 0d 00 ff
To print 16 bytes just change the size argument.
I can't think of common type having 16 bytes, so I'm not sure why you are trying to print it out as single number, usually the single-byte output like above is used in debuggers (until the user requests different size unit).
For quite a long time I use following function for printing content of memory area:
/*************************************************************/
/**
* Function to dump memory area
* \param address start address
* \param len length of memory area
*/
/*************************************************************/
void dump( void* address, int len ) noexcept{
int i;
printf("dump from 0x%lX (%d bytes)\n",(long)address, len);
printf("=============================================");
for(i=0; i<len; i++){
if(i%16==0){printf("\n");}
printf("%2X ",(*((char*)address+i))&0xFF);
}
printf("\n=============================================\n");
}
For C programs delete the noexcept keyword.
I'm trying to allocate an array of struct and I want each struct to be aligned to 64 bytes.
I tried this (it's for Windows only for now), but it doesn't work (I tried with VS2012 and VS2013):
struct __declspec(align(64)) A
{
std::vector<int> v;
A()
{
assert(sizeof(A) == 64);
assert((size_t)this % 64 == 0);
}
void* operator new[] (size_t size)
{
void* ptr = _aligned_malloc(size, 64);
assert((size_t)ptr % 64 == 0);
return ptr;
}
void operator delete[] (void* p)
{
_aligned_free(p);
}
};
int main(int argc, char* argv[])
{
A* arr = new A[200];
return 0;
}
The assert ((size_t)this % 64 == 0) breaks (the modulo returns 16). It looks like it works if the struct only contains simple types though, but breaks when it contains an std container (or some other std classes).
Am I doing something wrong? Is there a way of doing this properly? (Preferably c++03 compatible, but any solution that works in VS2012 is fine).
Edit:
As hinted by Shokwav, this works:
A* arr = (A*)new std::aligned_storage<sizeof(A), 64>::type[200];
// this works too actually:
//A* arr = (A*)_aligned_malloc(sizeof(A) * 200, 64);
for (int i=0; i<200; ++i)
new (&arr[i]) A();
So it looks like it's related to the use of new[]... I'm very curious if anybody has an explanation.
I wonder why you need such a huge alignment requirement, moreover to store a dynamic heap allocated object in the struct. But you can do this:
struct __declspec(align(64)) A
{
unsigned char ___padding[64 - sizeof(std::vector<int>)];
std::vector<int> v;
void* operator new[] (size_t size)
{
// Make sure the buffer will fit even in the worst case
unsigned char* ptr = (unsigned char*)malloc(size + 63);
// Find out the next aligned position in the buffer
unsigned char* endptr = (unsigned char*)(((intptr_t)ptr + 63) & ~63ULL);
// Also store the misalignment in the first padding of the structure
unsigned char misalign = (unsigned char)(endptr - ptr);
*endptr = misalign;
return endptr;
}
void operator delete[] (void* p)
{
unsigned char * ptr = (unsigned char*)p;
// It's required to call back with the original pointer, so subtract the misalignment offset
ptr -= *ptr;
free(ptr);
}
};
int main()
{
A * a = new A[2];
printf("%p - %p = %d\n", &a[1], &a[0], int((char*)&a[1] - (char*)&a[0]));
return 0;
}
I did not have your align_malloc and free function, so the implementation I'm providing is doing this:
It allocates larger to make sure it will fit in 64-bytes boundaries
It computes the offset from the allocation to the closest 64-bytes boundary
It stores the "offset" in the padding of the first structure (else I would have required a larger allocation space each time)
This is used to compute back the original pointer to the free()
Outputs:
0x7fff57b1ca40 - 0x7fff57b1ca00 = 64
Warning: If there is no padding in your structure, then the scheme above will corrupt data, since I'll be storing the misalignement offset in a place that'll be overwritten by the constructor of the internal members.
Remember that when you do "new X[n]", "n" has to be stored "somewhere" so when calling delete[], "n" calls to the destructors will be done. Usually, it's stored before the returned memory buffer (new will likely allocate the required size + 4 for storing the number of elements). The scheme here avoid this.
Another warning: Because C++ calls this operator with some additional padding included in the size for storing the array's number of elements, you'll might still get a "shift" in the returned pointer address for your objects. You might need to account for it. This is what the std::align does, it takes the extra space, compute the alignment like I did and return the aligned pointer. However, you can not get both done in the new[] overload, because of the "count storage" shift that happens after returning from new(). However, you can figure out the "count storage" space once by a single allocation, and adjust the offset accordingly in the new[] implementation.
I've been given a c api to work with and the minimum docs.
Developer is not around at the moment and his code is returning unexpected values (arrays not of expected length)
Im having problems with methods that return pointers to arrays and was wondering am I iterating over them correctly.
Q:does the following always return the correct len of an array?
int len=sizeof(sampleState)/sizeof(short);
int len=sizeof(samplePosition)/sizeof(int);
typedef unsigned char byte;
int len=sizeof(volume)/sizeof(byte);
And I iterate over the array using the pointer and pointer arithmetic (am I doing it correctly for all types below)
And last example below is multidimensional array? Whats the best way to iterate over this?
thanks
//property sampleState returns short[] as short*
short* sampleState = mixerState->sampleState;
if(sampleState != NULL){
int len=sizeof(sampleState)/sizeof(short);
printf("length of short* sampleState=%d\n", len);//OK
for(int j=0;j<len;j++) {
printf(" sampleState[%d]=%u\n",j, *(sampleState+j));
}
}else{
printf(" sampleState is NULL\n");
}
//same with int[] returned as int*
int* samplePosition = mixerState->samplePosition;
if(samplePosition != NULL){
int len=sizeof(samplePosition)/sizeof(int);
printf("length of int* samplePosition=%d\n", len);//OK
for(int j=0;j<len;j++) {
printf(" samplePosition[%d]=%d\n",j, *(samplePosition+j));
}
}else{
printf(" samplePosition is NULL\n");
}
Here byte is type def to
typedef unsigned char byte;
so I used %u
//--------------
byte* volume = mixerState->volume;
if(volume != NULL){
int len=sizeof(volume)/sizeof(byte);
printf("length of [byte* volume = mixerState->volume]=%d\n", len);//OK
for(int j=0;j<len;j++) {
printf(" volume[%d]=%u\n",j, *(volume+j));
}
}else{
printf(" volume is NULL\n");
}
Here is int[][] soundFXStatus.
do I just use same method above and have 2 loops?
//--------------
int** soundFXStatus = mixerState->soundFXStatus;
The sizeof(array)/sizeof(element) trick only works if you have an actual array, not a pointer. There's no way to know the size of an array if all you have is a pointer; you must pass an array length into a function.
Or better use a vector, which has a size function.
sizeof(sampleState)/sizeof(short);
This will only give the length of an array if sampleState is declared as an array, not a pointer:
short array[42];
sizeof(array)/sizeof(short); // GOOD: gives the size of the array
sizeof(array)/sizeof(array[0]); // BETTER: still correct if the type changes
short * pointer = whatever();
sizeof(pointer)/sizeof(short); // BAD: gives a useless value
Also, beware that a function argument is actually pointer even if it looks like an array:
void f(short pointer[]) // equivalent to "short * pointer"
{
sizeof(pointer)/sizeof(short); // BAD: gives a useless value
}
In your code, sampleState is a pointer; there is no way to determine the length of an array given only a pointer to it. Presumably the API provides some way to get the length (since otherwise it would be unusable), and you'll need to use that.
In C++, this is one reason why you would prefer std::vector or std::array to a manually allocated array; although that doesn't help you since, despite the question tags, you are using C here.
int len=sizeof(sampleState)/sizeof(short);
int len=sizeof(samplePosition)/sizeof(int);
sizeof is done at compile time, so this approach doesnt work if the length of the arrays are not known at compile time (for example the memory is reserved using a malloc).
ok ignore the method I used above it was all wrong - though you do need to know the length of the array which I finally got from the API developer.
I am trying to use implement the LSB lookup method suggested by Andrew Grant in an answer to this question: Position of least significant bit that is set
However, it's resulting in a segmentation fault. Here is a small program demonstrating the problem:
#include <iostream>
typedef unsigned char Byte;
int main()
{
int value = 300;
Byte* byteArray = (Byte*)value;
if (byteArray[0] > 0)
{
std::cout<< "This line is never reached. Trying to access the array index results in a seg-fault." << std::endl;
}
return 0;
}
What am I doing wrong?
I've read that it's not good practice to use 'C-Style' casts in C++. Should I use reinterpret_cast<Byte*>(value) instead? This still results in a segmentation fault, though.
Use this:
(Byte*) &value;
You don't want a pointer to address 300, you want a pointer to where 300 is stored. So, you use the address-of operator & to get the address of value.
While Erik answered your overall question, as a followup I would say emphatically -- yes, reinterpret_cast should be used rather than a C-style cast.
Byte* byteArray = reinterpret_cast<Byte*>(&value);
The line should be:
Byte* byteArray = (Byte*)&value;
You should not have to put the (void *) in front of it.
-Chert
char *array=(char*)(void*)&value;
Basically you take a pointer to the beginning of the string and recast it to a pointer to a byte.
#Erik already fixed your primary problem, but there is a subtle one that you still have. If you are only looking for the least significant bit, there is no need to bother with the cast at all.
int main()
{
int value = 300;
if (value & 0x00000001)
{
std::cout<< "LSB is set" << std::endl;
}
return 0;
}