How to iterate through the bytes of a void* in C++? - c++

What would be the best way to iterate through each byte of a void* buffer, and a assign a value to each depending on certain conditions?
unsigned int bufSize = 100; //could be any value
void* buffer = malloc(bufSize);
char* bufferPointer = static_cast<char*>(buffer);
for (unsigned int i = 0; i < bufSize; i++){
if (i % 2 == 0){
bufferPointer[i] = 0x00;
}
else{
bufferPointer[i] = 0xff;
}
}
buffer = static_cast<void*>(bufferPointer);
Why doesn't this work? I tried converting to a char* to iterate over each byte.

You need to cast the void* to an unsigned char*. You can then use pointer arithmetic to traverse the block of memory that you own, and set values by pointer dereference.
Remember that pointer arithmetic is only valid within arrays. For this purpose an object can be considered to be an array of length 1. Also, and perhaps confusingly, an array of N int elements will equate to an array of N * sizeof(int) unsigned char elements.

Related

Retrieve pointer that can acess all the elements of arrays stored in a std::vector

Is it possible to have a pointer that points to the contiguous buffer that is used by a vector?
For example (see below please), here std::vector<unsigned char*> vec contains two differently sized unsigned char* pointers. I need to have a buffer pointer that points to all pushed data in this vector. I'd guess that this is possible as the standard guarantees that a vector uses a contiguous memory buffer, right?
P.S. are the two ways of printing the elements of the vector I use in this example fine? (the two for loops)
unsigned char* data1 = new unsigned char[3];
data1[0] = 'a';
data1[1] = 'b';
data1[2] = 'c';
unsigned char* data2 = new unsigned char[1];
data2[0] = 'x';
std::vector<unsigned char*> vec;
vec.push_back(data1);
vec.push_back(data2);
for (size_t i = 0; i < vec.size(); i++) {
std::cout << vec[i];
}
std::cout << "\n";
for (auto iter = vec.begin(); iter != vec.end(); iter++) {
std::cout << (*iter);
}
std::cout << "\n\n";
unsigned char* buffer = (unsigned char*) vec[0];
Does buffer point to all data in vec? i.e. buffer[0] = a, buffer[1] = b, buffer[2] = c, buffer[3] = x ?
Does buffer point to all data in vec? i.e. buffer[0] = a, buffer[1] = b, buffer[2] = c, buffer[3] = x?
It doesn't. It points to the beggining of the array stored in first element of the vector.
Are the two ways of printing the elements of the vector I use in this example fine?
They are not, those arrays are not null terminated, they can't be printed as strings.
Is it possible to have a pointer that points to the contiguous buffer that is used by a vector?
Yes, it's possible.
If you'd like a pointer that can correctly access all the data in the vector, including individual elements of the unsigned char array members you'd want:
unsigned char **buffer = vec.data();
And the access:
for(size_t i = 0; i < 3; i++)
std::cout << buffer[0][i]; //indexing like a 2D array, albeit unbalanced
//output: abc
std::cout << buffer[1][0]; //output: x
Note that I use a cycle to access each element of data1 instead of simply treating it like a string, and this is because it is not a string, aka a null terminated char array.
Needless to say that you will need to know how many elements are stored in each array.
Alternatively you can null terminate them:
unsigned char* data1 = new unsigned char[4];
//...
data1[3] = '\0';
And
unsigned char* data2 = new unsigned char[2];
//...
data2[1] = '\0';
Here printing them like strings:
std::cout << buffer[0];
std::cout << buffer[1];
Using a null terminator has the extra benefit of allowing you to know the size of the arrays at any time using strlen((char*)buffer[0]).
You want the data() method on vector. It will return a pointer to the data, assuming that the vector size is greater than zero. If it is zero, then data() will return something but using it is undefined.
Read https://en.cppreference.com/w/cpp/container/vector/data

Generate random char/digit

I`m trying to found fastest way to generate random digit/char array.
char *randomGet(int num) {
srand(time(NULL));
const char ab[37] = { "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ" };//Alphabet&Digit
char *targ = new char[num];
for (int i = 0; i < num; i++) {
strcat(targ, ab[rand() % 38]);
}
return targ;
}
So far I've come up with this, but it does not work (argument of type char is incompatible with parameter of type const char *).
Help me find the best solution to my problem. Ty.
strcat() takes a char* as input, but you are giving it a single char instead, thus the compiler error.
Also, the buffer that strcat() writes to must be null terminated, but your targ buffer is not null terminated initially, and you are not allocating enough space for a final null terminator anyway.
You don't need to use strcat() at all. Since you are looping anyway, just use the loop counter as the index where to write in the buffer:
Also, you are using the wrong integer value when modulo the return value of rand(). You are producing a random index that may go out of bounds of your ab[] array.
Try this instead:
char *randomGet(int num)
{
srand(time(NULL));
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ"; //Alphabet&Digit
char *targ = new char[num+1];
for (int i = 0; i < num; ++i) {
targ[i] = ab[rand() % 36];
}
targ[num] = '\0';
return targ;
}
I'd make two changes. First, make the internal source array static:
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ";
Note that this version does not specify the array size; the compiler will figure it out from the initializer.
Second, pass in a pointer to the target array:
void randomGet(char* targ, int num) {
static const char ab[] = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ";
for (int i = 0; i < num - 1; ++i)
targ[i] = ab[rand() % (sizeof ab - 1)];
targ[num - 1] = '\0';
}
This way, the caller decides how to allocate memory for the string.

How to set quantity of elements of the char array of a variable

How to set quantity of elements of the char array of a variable?
This is my code:
long int len = strlen(qq);
//char buff[10];
//sprintf(buff, "%d", len);
//MessageBoxA(0,buff,0,0);
char key[len] = "12345678901234567890123456789..";//error
char crypt[len];//error
for (int i = 0; i < len; i++) {
crypt[i] = text[i] ^ key[i];
}
In C++ an array can only be staticly sized using a constant variable that is known at compile time, which your len is not. Note that some compiler extensions DO allow this, as it's allowed in C. But for pure C++ you instead can use dynamic memory allocation (this allocates on the heap instead of the stack):
char* key = new char[len];
char* crypt = new char[len];
Note that a char* can be used the same as a char[] (you can still use array indexing, the rest of your code remains unchanged).
Because the array is now allocated on the heap, to avoid memory leaks you must manually free the memory when you no longer need it using delete e.g. at the end of the function after you loop:
delete[] key;
delete[] crypt;
Since you specified the winapi tag, it may be that the CString class would be a viable solution.
For your key though, you don't even need to allocate an array dynamically. You could use the modulo operator:
static const char key[] = "1234567890";
const size_t keyLength = strlen(key);
CString crypt(0, len);
for (int i = 0; i < len; i++) {
crypt[i] = text[i] ^ key[i & keyLength];
}

how to find length of char array containing zeros as elements

wondering how would I find the length of char array .
for example
char buffer[20];
buffer[0] = 0x01;
buffer[1] = 0x02;
buffer[3] = 0x00;
buffer[4] = 0x04;
buffer[5] = 0x01;
buffer[6] = 0x02;
buffer[7] = 0x00;
buffer[8] = 0x04;
std::cout << "the len of array = "<< strlen(buffer) << std::endl;
o/p = the len of array = 3
expected o/p = 8
NOw issue is zeros can occur anywhere in the array of character elements.and I need true len i.e 8
Arrays in C (or C++) don't keep track of how much data has been stored in them. If you want to know the size of the stored data (as opposed to the size of the array), you'll need to track that yourself in another variable, or use a sentinel (such as NULL) that marks the end of the stored data.
Alternately, since you appear to be using C++ (despite the C tag), you can use a std::vector or std::string which tracks the size for you.
In C++ you would use a std::vector<char> or a std::string. Both store the length independently of the data so can hold zeros in them.
Beware that 'c' style literal strings are always zero terminated, so the following code gives you an empty string because the NUL terminates the string construction early.
std:string foo("\0Hello, world!");
When you have an array, you can use sizeof to get the total memory used by the array.
char buffer[20];
//
// ...
//
size_t size = sizeof(buffer); // This gives you total memory needed to hold buffer.
size_t length = sizeof(buffer)/sizeof(char); // In this case size and length will be
// same since sizeof(char) is 1.
If you have an array of other types,
int buffer[20];
//
// ...
//
size_t size = sizeof(buffer); // This gives you total memory needed to hold buffer.
size_t length = sizeof(buffer)/sizeof(int); // The length of the array.
There are pitfalls to be aware of using sizeof to get the memory used by an array. If you pass buffer to a function, you lose the ability to compute the length of the array.
void foo(char* buffer)
{
size_t size = sizeof(buffer); // This gives you the size of the pointer
// not the size of the array.
}
void bar()
{
char buffer[20];
// sizeof(buffer) is 20 here. But not in foo.
foo(buffer);
}
If you need to be able to compute the length of the array at all times, std::vector<char> and std::string are better choices.
void foo(std::vector<char>& buffer)
{
size_t size = buffer.size() // size is 20 after call from bar.
}
void bar()
{
std::vector<char> buffer(20);
size_t size = buffer.size() // size is 20.
foo(buffer);
}

Can't delete an unsigned char* after inserting data

I have this code
unsigned char _binary[] = {'1','1','1','0','0','0','1','0',NULL};
int length = 0;
for(length=0;_binary[length];length++);
unsigned char *_hexaActual = new unsigned char;
ConvertBinaryToHexaDecimal(_binary, length, _hexaActual);
string _actual((char*)_hexaActual);
delete[] _hexaActual; // crashes here
Now the ConvertBinaryToHexaDecimal is
void ConvertBinaryToHexaDecimal(const unsigned char* _inputBinary, unsigned int _intputLength, unsigned char* _outputHexaDecimal)
{
const unsigned char _hexaDecimalSymbols[16] = {'0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F'};
char* _binary =(char*) malloc(sizeof(char));
int _binaryIndex,_inputIndex;
for(_binaryIndex=0; _binaryIndex < _intputLength%4 ;_binaryIndex++) // padding extra 0's to make the length multiple of 4
_binary[_binaryIndex] = '0';
for(_inputIndex=0; _inputIndex < _intputLength ;_inputIndex++)
_binary[_inputIndex + _binaryIndex] = _inputBinary[_inputIndex];
_binary[_inputIndex + _binaryIndex] = NULL;
_intputLength = _inputIndex + _binaryIndex;
for( _inputIndex=0; _inputIndex < _intputLength; _inputIndex +=4)
{
int _binaryValue = _binary[_inputIndex] - 48;
int _binaryValue1 = _binary[_inputIndex+1] - 48;
int _binaryValue2 = _binary[_inputIndex+2] - 48;
int _binaryValue3 = _binary[_inputIndex+3] - 48;
int _hexValue = _binaryValue3 * 1;
_hexValue += _binaryValue2 * 2;
_hexValue += _binaryValue1 * 4;
_hexValue += _binaryValue * 8;
_outputHexaDecimal[_inputIndex/4] = _hexaDecimalSymbols[_hexValue];
}
_outputHexaDecimal[_inputIndex/4] = NULL;
}
It outputs corretly a hexa decimal value. But when I try to delete it the program crashes.
EDIT: The crash message says HEAP CORRUPTION DETECTED.
You allocated a single unsigned char with new, so you should call delete, not delete []. The latter is for arrays allocated with new [].
You need
delete _hexaActual;
Note that this type of manual allocations and de-allocations are error prone and exception unsafe. It is likely that you can implement your code using standard library containers and algorithms.
Edit: besides that error, you have a few more: The most important one, in the function ConvertBinaryToHexaDecimal, you are passing a pointer to a single unsigned char, but you are treating it like an array:
_outputHexaDecimal[_inputIndex/4] = ....
Next, you hve a memory leak. You allocate here:
char* _binary =(char*) malloc(sizeof(char));
and never call free.
You only allocated one char for _hexaActual, but you are writing many values to it inside ConvertBinaryToHexaDecimal. You need allocate enough space for the characters you are going to put in there. length/4 + 2 should do it.
unsigned char *_hexaActual = new unsigned char[length/4 + 2];