How do I assign existing array values into an array pointer? - c++

I have a program that needs to use a large array (700,000 elements). I tried to assign it as per a normal array:
byte array1[700000] = {0xE8, 0x39, 0xF4, 0xB7, 0x69, ~~699995 other values~~ };
But then, I was met with a segmentation fault. After a bit of research, it was suggested that I put it on the heap. So, I did:
byte* array1 = (byte*) malloc(700000 * sizeof(byte) /* Just to be safe */);
I've used pointers before, and normally I would use a loop to mess around with it. But, in this case, all of the values already exist. How do I put all of those in the new array1? I cannot use external files (i.e. I cannot read from a .txt file).
This does not work (Too many initializer values according to Visual Studio):
byte* array1 = (byte*) malloc(700000 * sizeof(byte));
array1 = { ~~ 700k comma-separated values ~~ };
Sample on how I plan to use it:
#include <stdio.h>
int main(int argc, char* argv[]) {
byte big_array[700000] = {0xE8, 0x39, 0xF4, ~~699995 other values~~ };
some_function(big_array);
return 0;
}

If you are able to use a C++11 compiler, you should use a std::vector.
std::vector<byte> array1 = {0xE8, 0x39, 0xF4, 0xB7, 0x69, ~~9995 other values~~ };

Related

Passing the Number of Elements in an Array to Function?

I am writing a DLL that passes a char array to a function. I define that char array with 22 elements here:
unsigned char data[22] = { 0x00, 0x0A, 0x00, 0x09, 0x70, 0x00, 0x72, 0x00,
0x6F, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x67, 0x00, 0x75, 0x00,
0x79, 0x00 };
Now, I try to pass this array to my function declared as:
bool sendData(unsigned char* sData, unsigned long sSize);
With these arguments:
sendData(data, 22);
This code compiles, but crashes the program when this function is called. Taking a closer look while debugging, I can see that there's an access violation in my function sendData. Looking even further, I see the values of data and sData at run-time:
data points to the 22 byte char array with correct values (obviously)
sData points to a char array that is null-terminated by the first byte, only containing one value (0)
It is clear to me that the compiler does not know to allocate 22 bytes for sData, simply because I do not specify any length for it. So my question is:
How do I specify the length of the sData so that the argument
passed won't terminate early?
If I'm wrong about the issue, please correct me and explain it further. Thanks for any help in advance!
EDIT:
I understand that \0 (the first byte and many more in data) is a null-terminator and will prematurely end the array. What I am asking is how to avoid this. My understanding is that sData is never given a specific length and therefore stops on \0, but I may be wrong.
I was asked to supply my sendData function:
bool sendData(unsigned char* sData, unsigned long sSize)
{
try
{
Send(sData, sSize);
return true;
}
catch (...)
{
return false;
}
}
Send is calling a function from another module, but isn't relevant to the issue, as the error occurs beforehand when the sData argument is passed to sendData.
No allocation of sData is going to happen, it just points to your array. It displays as empty in the debugger because it displays a char* as a string, and strings end when there is a '/0', your first byte. This does not mean sData does not have the correct data. Write sData[0]. sData[1], etc, in your debugger to see the correct values.

Remove null byte every X byte c++ WINAPI

I have a buffer type like this:
unsigned char buffer[] = {
0xB8, 0xB8, 0x00, 0xB8, 0xB8, 0x00, 0xB8, 0xB8, 0x00, 0xB8, 0xB8, 0x00,..
};
So I need to remove the null byte every X (every 2 bytes in this example). I don't want to remove all null byte because in my buffer I have melt bytes.
So just need to remove a range and in WinAPI. How can I do that?
I'm still not very comfortable with C++, also the buffer can be big.
I think the right way is by copy the buffer by memcpy in a loop but I can't find the syntax.
It seems that you don't want to use any of the more powerful features of C++ so I suspect that you are really looking for a C style routine. That would look like this:
void copyskip(void *dest, const void *src, size_t srclen, size_t skip)
{
size_t destidx = 0;
for (size_t srcidx=0; srcidx<srclen; )
{
if ((srcidx+1) % skip != 0)
{
((char*)dest)[destidx] = ((char*)src)[srcidx];
destidx++;
}
srcidx++;
}
}
You'd need to allocate the destination buffer before calling. And for your example you would pass 3 for the skip parameter.
Personally I'd much rather do it using C++ standard containers, but this is what I think you asked for.

Error when passing arguments and convert it to hexadecimal

How could insert text by argument and automatically transform it to hex?
I tried with:
unsigned char aesKey[32] = argv[1];
but get errors
The output would be like this:
unsigned char aesKey[32] = {
0x53, 0x28, 0x40, 0x6e, 0x2f, 0x64, 0x63, 0x5d, 0x2d, 0x61, 0x77, 0x40, 0x76, 0x71, 0x77, 0x28,
0x74, 0x61, 0x7d, 0x66, 0x61, 0x73, 0x3b, 0x5d, 0x66, 0x6d, 0x3c, 0x3f, 0x7b, 0x66, 0x72, 0x36
};
unsigned char *buf;
aes256_context ctx;
aes256_init(&ctx, aesKey);
for (unsigned long i = 0; i < lSize/16; i++) {
buf = text + (i * 16);
aes256_encrypt_ecb(&ctx, buf);
}
aes256_done(&ctx);
Thanks in advance
In C and C++, when you have code like
char name[]="John Smith";
The compiler knows at compile time what the size of that char array, and all the values will be. So it can allocate it on the stack frame and assign it the value.
When you have code like
char * strptr = foo();
char str[] = strptr;
The compiler doesn't know what the size and value of the string pointed by strptr is. That is why this is not allowed in C/C++.
In other words, only string literals can be assigned to char arrays, and that too only at the time of declaration.
So
char name[] = "John Smith";
is allowed.
char name[32];
name = "John Smith";
is not allowed.
Use memcpy
So you could use memcpy. (Or use c++ alternative that others have alluded to)
unsigned char *aesKey;
size_t len = (strlen(argv[1])+1)*sizeof(unsigned char);
aesKey = malloc(len);
memcpy(aesKey, argv[1], len);
The old solution
(here is my previous answer, the answer above is better)
So you need to use strncpy.
unsigned char aesKey[32];
strncpy((char *) aesKey, argv[1], 32);
Notice the routine is strncpy not strcpy. strcpy is unsafe. (Thanks PRouleau for the arg fix)
If strncpy is not available in Visual Studio then you may have to try strcpy_s (Thanks Google: user:427390)
In C/C++, the compiler does not automatically manipulate the arrays. You have to specify how to copy them.
The good old way is with memcpy(). A more modern way is with std::copy(). In any case, you have to validate the length of argv[1] before copying into aesKey.
For the conversion into hex, you probably have to transform a string like "AAEE3311" (up to 2*32 chars) into bytes. You should use std::istringstream and fill your aesKey position by position.
Ex:
std::istringstream Input(argv[1]);
Input >> std::hex >> aesKey[0];
I would imagine a program being called as below -
myprog 0x53 0x28 0x40 0x6e 0x2f 0x64 0x63
Inside the program I would have a loop to assign the arguments to the array -
const int size = 32;
unsigned char aesKey[size];
char* p;
for (int i = 1; i < argc || i < size; ++i)
{
aesKey[i] = (unsigned char)strtol(argv[i], &p, 16);
}

How can I convert 0x70, 0x61, 0x73 ... etc to Pas ... etc in C++?

I am using MSVC++ 2010 Express, and I would love to know how to convert
BYTE Key[] = {0x50,0x61,0x73,0x73,0x77,0x6F,0x72,0x64};
to "Password" I am having a lot of trouble doing this. :( I will use this knowledge to take things such as...
BYTE Key[] { 0xC2, 0xB3, 0x72, 0x3C, 0xC6, 0xAE, 0xD9, 0xB5, 0x34, 0x3C, 0x53, 0xEE, 0x2F, 0x43, 0x67, 0xCE };
And other various variables and convert them accordingly.
Id like to end up with "Password" stored in a char.
Key is an array of bytes. If you want to store it in a string, for example, you should construct the string using its range constructor, that is:
string key_string(Key, Key + sizeof(Key)/sizeof(Key[0]));
Or if you can compile using C++11:
string key_string(begin(Key), end(Key));
To get a char* I'd go the C way and use strndup:
char* key_string = strndup(Key, sizeof(Key)/sizeof(Key[0]));
However, if you're using C++ I strongly suggest you use string instead of char* and only convert to char const* when absolutely necessary (e.g. when calling a C API). See here for good reasons to prefer std::string.
All you are lacking is a null terminator, so after doing this:
char Key_str[(sizeof Key)+1];
memcpy(Key_str,key,sizeof Key);
Key_str[sizeof Key] = '\0';
Key_str will be usable as a regular char * style string.

vector of char array

I have the following code:
static unsigned char S0_gif[] = {
0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x0f, 0x00, 0x0f, 0x00, 0x91, 0x02,
..
};
It's a hex representation of a gif file. I have 500 gifs that I need to store like that so I want to use a vector to make it easier for access.
Something like:
vector<char[]> gifs;
gif.push_back( {0x47, 0x49,..} );
Then in the loop:
{
MakeImage(gif[i], sizeof gif[i] );
}
I cannot find the right code for that. Any help would be greatly appreciated.
Petry
You cant do that, because vectors store constant sized structures, and youre's are variable sized. What you can do however, is store a vector of vector :)
vector<vector<char> > gifs; // note the neccessary space between > >
gif.push_back( vector<char>( S0_gif, S0_gif + sizeof(S0_gif) ) );
Then in the loop:
{
MakeImage( gifs[i] );
}
Another idea, if they are indeed stored as static variables, is not to store the data twice:
vector< unsigned char * > gifs;
vector< size_t > gifsizes;
gifs.push_back( S0_gif );
gifsizes.push_back( sizeof(S0_gif) );
Then in the loop:
{
MakeImage( gifs[i], gifsizes[i] );
}
Disclaimer : I probably forgot some &'s, feel free to correct me.
Looks like you are storing all 500 GIF files in a row. You cannot detect size of each without parsing its header. If your function MakeImage could parse GIF header you could return pointer to the next image from it.
Then the loop will look like:
char* img_ptr = S0_gif;
while ( img_ptr ) img_ptr = MakeImage( img_ptr );
I believe that the best solution is to generate a C/CPP file that declares a vector of images. All the rest means writing code, which is not generally recommended for a lot of initialization (my opinion).
unsigned char *Array[]={
S0_gif,
S1_gif,
S2_gif,
S3_gif,
...
};
The code for generating this can be easily written in a scripting language (bash, perl, python, etc). It should be something like this:
print "char *Array[]={"
for i in range(0,500)
print "S"+i+"_gif"
print "};"
Is this a solution to your question?