Using linear storage to implement a 2D array - c++

I need to create a function that helps to implement a 2D array using linear storage in C++. The first of these functions is two_d_store(), which takes as arguments the following: base address in memory of region to be used as 2D array, size in bytes of an array entry, 2 array dimensions, and 2 index values. So with this two_d_store() function:
int d[10][20];
d[4][0] = 576;
can be replaced with
char d[200*sizeof(int)];
two_d_store(d, sizeof(int), 10, 20, 4, 0, 576);
So is there a simple way to implement this function without using arrays?

For any weird or not reason, if u dont want to have the standard way to access or set your memory structs, you could use
memcpy(void *dst, const void *src, size_t len);
Its a C function but it works 100% for C++ too.
Here are some general memory handling functions i found, good luck!:
void *memchr(const void *ptr, int ch, size_t len)
memchr finds the first occurence of ch in ptr and returns a pointer to it (or a null pointer if ch was not found in the first len bytes
int memcmp(const void *ptr1, const void *ptr2, size_t len)
memcmp is similar to strcmp, except that bytes equal to 0 are not treated as comparison terminators.
void *memcpy(void *dst, const void *src, size_t len)
memcpy copies len characters from src to dst and returns the original value of dst
The result of memcpy is undefined if src and dst point to overlapping areas of memory
void *memmove(void *dst, const void *src, size_t len)
memmove is just like memcpy except that memmove is guaranteed to work even if the memory areas overlap
void *memset(void *ptr, int byteval, size_t len)
memset sets the first len bytes of the memory area pointed to by ptr to the value specified by byteval

I changed the last argument to a pointer, not value, bcs we don't know what type it is. The max_y param is not needed. First i compute on n_array_ptr the adress of cell we want to change, and then memcpy the size_of_type bytes from new_value pointer to n_array_ptr. This function can be used for arrays of all types, bcs we are casting it void* and calculating the adress of block where our cell starts, and copy'ing exectly size_of_type bytes.
#include <iostream>
#include <cstring>
using namespace std;
void two_d_store(void * array_ptr, size_t size_of_type, int max_y, int max_x, int y, int x, void* new_value) {
void * n_array_ptr = array_ptr + size_of_type * (y * max_x + x);
memcpy(n_array_ptr, new_value, size_of_type);
}
int main() {
int d[10*20];
int new_val = 576;
two_d_store(d, sizeof(int), 10, 20, 4, 0, &new_val);
cout<<d[4*20]; //[4][20]
return 0;
}

Related

How to determine cuda pointer is nullptr?

I want to determine a cuda memory is malloced or not in runtime. Or is there a way to determine a cuda pointer is a nullptr or not?
I want to determine the memory in cuda is nullptr or not for different process. I have a function as below.
__global__ void func(unsigned int *a, unsigned char *mask, const int len)
{
if (mask!= nullptr){// do something}
else {// do something else}
}
If the mask is processed by cudaMalloc, it should run into if-condition. Otherwise, it runs into else-condition.
This snippet could run:
int* a;
char* mask;
int len = 1024;
cudaMalloc(&a, sizeof(int) * len);
cudaMalloc(&mask, sizeof(char) * len);
func(a, mask, len);
And this snippet could also run:
int* a;
char* mask;
int len = 1024;
cudaMalloc(&a, sizeof(int) * len);
func(a, mask, len);
Is there a way to achieve this?
In the general case, pointer introspection in device code is not possible.
In your host code, if you do:
char* mask = nullptr;
and you guarantee both of these conditions:
If any cudaMalloc operation is run (on mask), you test the return value and do not allow further code progress (or do not allow any of the snippets that use mask to run) if the return value is not cudaSuccess
There is no usage of cudaFree on the mask pointer until such point in time where your code snippets that use it will never be run again
Then it should be possible to do what you are suggesting in device code:
if (mask!= nullptr){// do something}
else {// do something else}
On a successful cudaMalloc call, the allocated pointer will never be the nullptr.

How to convert a byte array of size 64 to a list of double values in Arduino C++?

void Manager::byteArrayToDoubleArray(byte ch[]) {
int counter = 0;
// temp array to break the byte array into size of 8 and read it
byte temp[64];
// double result values
double res[8];
int index = 0;
int size = (sizeof(ch) / sizeof(*ch));
for (int i = 0; i < size; i++) {
counter++;
temp[i] = ch[i];
if (counter % 8 == 0) {
res[index] = *reinterpret_cast<double * const>(temp);
index++;
counter = 0;
}
}
}
Here result would be a list of double values with count = 8.
Your problem is two things. You have some typos and misunderstanding. And the C++ standard is somewhat broken in this area.
I'll try to fix both.
First, a helper function called laundry_pods. It takes raw memory and "launders" it into an array of a type of your choice, so long as you pick a pod type:
template<class T, std::size_t N>
T* laundry_pods( void* ptr ) {
static_assert( std::is_pod<std::remove_cv_t<T>>{} );
char optimized_away[sizeof(T)*N];
std::memcpy( optimized_away, ptr , sizeof(T)*N );
T* r = ::new( ptr ) T[N];
assert( r == ptr );
std::memcpy( r, optimized_away, sizeof(T)*N );
return r;
}
now simply do
void Manager::byteArrayToDoubleArray(byte ch[]) {
double* pdouble = laundry_pods<double, 8>(ch);
}
and pdouble is a pointer to memory of ch interpreted as an array of 8 doubles. (It is not a copy of it, it interprets those bytes in-place).
While laundry_pods appears to copy the bytes around, both g++ and clang optimize it down into a binary noop. The seeming copying of bytes around is a way to get around aliasing restrictions and object lifetime rules in the C++ standard.
It relies on arrays of pod not having extra bookkeeping overhead (which C++ implementations are free to do; none do that I know of. That is what the non-static assert double-checks), but it returns a pointer to a real honest to goodness array of double. If you want to avoid that assumption, you could instead create each doulbe as a separate object. However, then they aren't an array, and pointer arithmetic over non-arrays is fraught as far as the standard is concerned.
The use of the term "launder" has to do with getting around aliasing and object lifetime requirements. The function does nothing at runtime, but in the C++ abstract machine it takes the memory and converts it into binary identical memory that is now a bunch of doubles.
The trick of doing this kind of "conversion" is to always cast the double* to a char* (or unsigned char or std::byte). Never the other way round.
You should be able to do something like this:
void byteArrayToDoubleArray(byte* in, std::size_t n, double* out)
{
for(auto out_bytes = (byte*) out; n--;)
*out_bytes++ = *in++;
}
// ...
byte ch[64];
// .. fill ch with double data somehow
double res[8];
byteArrayToDoubleArray(ch, 64, res);
Assuming that type byte is an alias of char or unsigned char or std::byte.
I am not completly sure what you are trying to achieve here because of the code (sizeof(ch) / sizeof(*ch)) which does not make sense for an array of undefined size.
If you have a byte-Array (POD data type; something like a typedef char byte;) then this most simple solution would be a reinterpret_cast:
double *result = reinterpret_cast<double*>(ch);
This allows you to use result[0]..result[7] as long as ch[] is valid and contains at least 64 bytes. Be aware that this construct does not generate code. It tells the compiler that result[0] corresponds to ch[0..7] and so on. An access to result[] will result in an access to ch[].
But you have to know the number of elements in ch[] to calculate the number of valid double elements in result.
If you need a copy (because - for example - the ch[] is a temporary array) you could use
std::vector<double> result(reinterpret_cast<double*>(ch), reinterpret_cast<double*>(ch) + itemsInCh * sizeof(*ch) / sizeof(double));
So if ch[] is an array with 64 items and a byte is really an 8-bit value, then
std::vector<double> result(reinterpret_cast<double*>(ch), reinterpet_cast<double*>(ch) + 8);
will provide a std::vector containing 8 double values.
There is another possible method using a union:
union ByteToDouble
{
byte b[64];
double d[8];
} byteToDouble;
the 8 double values will occupie the same memory as the 64 byte values. So you can write the byte values to byteToDouble.b[] and read the resultingdouble values from byteToDouble.d[].

Using the function fread() to read blocks of data in a file

If I use
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream ),
how can I derefence the data pointed by ptr?. Like if I have
int main()
{
void *ptr
fread(ptr,1,100,file);
printf("%s",ptr);
}
You misunderstand the purpose of void * ptr in the declaration of fread.
From http://en.cppreference.com/w/c/io/fread
buffer - pointer to the array where the read objects are stored
First, the argument must be a valid pointer where objects can be stored. Using
void *ptr;
fread(ptr,1,100,file);
will lead to undefined behavior since ptr does not point to anything valid.
Second, the reason for the argument type is void* to allow you to read all kinds of data from a stream. E.g.
// Read an integer
int i;
fread(&i, sizeof(int), 1, file);
// Read 10 integers
int a[10];
fread(a, sizeof(int), 10, file);
// Read a double
double d;
fread(&d, sizeof(double), 1, file);

segmentation fault using q sort?

I am trying to sort a pointer array of characters using qsort and keep getting a segmentation fault when I compile. I will post the code for my qsort call and the compare function and any help would be greatly appreciated.
//count declaration
size_t count = (sizeof (strPtrsQsort)/sizeof (*strPtrsQsort));
//function call
qsort ((char *)ptr, size, sizeof(char), compare);
//compare function
int compare (const void *a, const void *b)
{
const char **ia = (const char **)a;
const char **ib = (const char **)b;
return strcmp (*ia, *ib);
}
Judging by your qsort call, you are sorting an array of char elements: the base pointer type is passed to qsort as char * value and the element size is sizeof(char). However, your comparison function is written for an array of pointers to char. That's completely incorrect and inconsistent. That is what is causing the crash.
In the accompanying text you state that you are "trying to sort a pointer array of characters". Why in that case are you specifying the element size as sizeof(char) and not as, say, sizeof (char *)?
Note that even when you're required to work with C-style raw arrays you can still use C++ STL algorithms, since pointers are in fact RandomAccessIterators. For example, this works:
#include <algorithm>
#include <iostream>
#include <cstring>
static
bool compare(const char *a, const char *b)
{
return std::strcmp(a, b) < 0;
}
int main()
{
const char *stringarray[] = {
"zyxulsusd",
"abcdef",
"asdf"
};
std::sort(stringarray, stringarray + 3, compare);
// -----------^
// Just like a normal iterator the end iterator points
// to an imaginary element behind the data.
for(int i = 0; i < 3; i++) {
std::cout << stringarray[i] << std::endl;
}
return 0;
}
The primary advantage of this approach is type safety and it avoids thus most pitfalls common with C-style functions like qsort.

Checking size of an array through function

When I want to know the size of an array I do the following :
int array[30];
for(int i = 0; i < 30; i++)
array[i] = i+1; //Fill list
const int size = sizeof(array) / sizeof(array[0]);
But when I pass the array as argument in a function I will have a pointer in the function.
int size( int array[] )
{
return sizeof(array) / sizeof(array[0]); //Doesn't work anymore
}
This obviously doesn't work. But how do I get the size of that array in a function without taking another parameter for the size?
how do I get the size of that array in a function without taking
another parameter for the size?
You don't. The size of the array has to be somewhere visible to the compiler. Otherwise all you'll be able to pass is a pointer to the first element in the array.
However, you can use a template for the size, and make this a little more magical and seamless:
template <size_t N> int size (const int (&ary)[N])
{
assert (N == (sizeof(ary) / sizeof (ary[0])));
return N;
}
And further templatizing the type of elements, so this works with arrays of anything:
template <typename T, size_t N> int size (const T (&ary)[N])
{
assert (N == (sizeof(ary) / sizeof (ary[0])));
return N;
}
This is the way to get the size of the array using function templates:
template <typename T, size_t N>
constexpr size_t size(const T (&)[N] ) // omit constexpr if no C++11 support
{
return N
}
then
for(int i = 0; i < size(array); i++) { .... }
but you could simplify things by using an std::array (or std::tr1::array or boost::array if you don't have C++11) and using it's size() method.
In C, arrays in function parameters behave very strangely. Frankly, I think the language was very badly designed here.
void foo(int data[10]) {
int *p;
int a[10];
}
sizeof(p) will probably be 4 (or maybe 8). And sizeof(a) will be 40 (or 80).
So what do you think sizeof(data) will be? If you guessed 40 (or 80), you're wrong. Instead, its size is the same as sizeof(p).
If a C compiler see a [ immediately after the name of a parameter, it removes it and replaces it with a pointer, and data[10] becomes *data. (This is different from the decaying behaviour we get with arrays elsewhere, when a parameter, arrays are dealt with more drastically).
In fact, the following will compile despite the different sized arrays:
int foo(int data[10]);
int main() {
int hugearray[1000];
foo(hugearray); // this compiles!
}
The C compiler doesn't respect, in any way, the size of array parameters. I believe that compilers should issue a warning on any array parameters, and encourage us to use the * directly. I might allow [], but certainly not [10] given that it's ignored by the compiler.
If you want your C compiler to respect the size of arrays, you should pass the address of the array.
int foo(int (*data)[10]);
int main() {
int smallarray[10];
foo(&smallarray); // OK
int hugearray[1000];
foo(&hugearray); // error, as desired
}
Returning to the original question, parameter arrays know nothing about their size.
Use Macro
int findSize(int array[])
{
//This will not return size off array,it will just get starting address array and no information about boundaries
return sizeof(array) / sizeof(array[0]);
}
//But we can define a Macro for this
#define FIND_ARRAY_SIZE(array) (sizeof(array)/sizeof(array[0]))
int main()
{
int SampleArray[30];
printf("\nSize =%d ",sizeof(SampleArray) / sizeof(SampleArray[0]));
printf("\nSize from Function =%d ",findSize(SampleArray));
printf("\nSize from Macro =%d ",FIND_ARRAY_SIZE(SampleArray));
printf("\n");
return 0;
}
In C you can't find the size of array by passing array beginning address to function.
For example You have made function call
size(array); // You are calling function by passing address of array beginning element
int size( int array[] ) // this is same as int size(int *array)
{
return sizeof(array) / sizeof(array[0]); //Doesn't work anymore
}
Here sizeof(array) will give you the size of pointer. that is architecture dependent.
And if you pass character array instead of int array and that too if the character array was nulterminated then You can use strlen().This is the only way we can find the size of array.
strlen() counts till nul occurrence, You can use this trick However allocate memory for one more element to your array or declare your array with MAX_SIZE+1 .When ever if you store array elements of size n then store a known value inside array[n] and while finding size check against that value like strlen() Checks for Nul character.