Memory Managing QByteArray::fromRawData() - c++

In my program I have a function that processes some data and sends it back. In the function I allocate a new byte array with the following:
byte *buffer = new byte[bufferSize];
I then pass that to a library which fills it with some data. Once it's done, I want to send it back as a QByteArray. So I call:
myByteArray = QByteArray::fromRawData(reinterpret_cast<const char*>(buffer), bufferSize);
The byte array gets returned back and everything runs fine, however I now have a memory leak (pretty sure since my RAM usage skyrockets since I call this thousands of times). When I allocate buffer with new, I can't delete it after calling fromRawData because myByteArray shares the same data pointer. The documentation states The bytes are not copied. The QByteArray will contain the data pointer.
So my question is, how can I ensure that buffer gets deleted when myByteArray goes out of scope? It goes out of scope in the class the function was called from.
Thanks for your time.

Instead of manually allocating the array with new[], you can start directly with a QByteArray.
QByteArray myByteArray;
myByteArray.resize( bufferSize );
byte * buffer = myByteArray.data(); // Pointer to the memory allocated by the QByteArray
// Pass 'buffer' to library function..

Related

Character buffer being overrun while reading file

I'm trying to read data from a file but I'm getting a STATUS_STACK_BUFFER_OVERRUN error and the app crashes.
I have a struct:
struct BSPEntities
{
char* ents;
};
And I'm reading the file:
BSPEntities entities
ifstream mapfile;
int size = 54506;
int offset = 5182600;
entities.ents = new char[size];
mapfile.seekg(offset, ios::beg);
mapfile.read((char *)(&entities.ents), size);
"size" and "offset" are values loaded from the file and known to be valid. I have preprocessor directives #pragma pack(1) and #pragma push around the BSPEntities struct.
Thanks.
&entities.ents is a pointer to a pointer to char. The object pointed to (a pointer to char) is probably only 4 or 8 bytes depending on the architecture you're targeting, but you're trying to write 54,506 bytes to it. Obviously 54,506 is larger than 8, so you're writing past the end of the pointer, and the behavior is undefined.
That read should just be mapfile.read(entities.ents, size);
Also you don't need to mess around with #pragma pack here, unless there's something more complicated going on that you're not showing.
mapfile.read((char *)(&entities.ents), size);
Should be
mapfile.read(entities.ents, size);
Instead of passing the address of the heap memory block that ents points to, you are passing the address of ents itself. And since ents is being allocated on the stack, you are reading bytes onto the stack until it overruns.

How to append a char* to the end of a void*?

Assume we have defined a char* as follow:
char *x;
And we have a function like it:
void append(void *y, char *z);
This function appends it's second parameter (where the pointer z is pointing at) to the end of a string that the pointer y is pointing to it's beginning. The reason that I am restricted to have the first parameter to be void* is that I need to override a libcurl function:
size_t header_callback(char *buffer, size_t size, size_t nitems, void *userdata);
Any time the header_callback function is called I need to append buffer to the end of userdata. The userdata pointer is pointing to beginning of a string.
According to documentation you linked, userdata is a pointer previously supplied to CURLOPT_HEADERDATA. Something like this might work for you.
size_t header_callback(char *buffer, size_t size, size_t nitems, vector<string> *userdata)
{
userdata->push_back(string(buffer, size*nitems));
return size*nitems;
}
//...
vector<string> headers;
curl_easy_setopt(curl, CURLOPT_HEADERDATA, &headers);
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_callback);
//...
It is impossible to implement your
void append(void *y, char *z);
in such a way that it could append a non-null terminated character sequence.
The char *buffer given to the callback is non-null terminated.
Also, you can convert the void pointer to the correct type of the buffer in the callback, before calling the append. That must be done eventually, since you cannot append anything to void.
You hardly need an external function since appending is quite trivial. Assuming your void* points to a std::string:
auto bytes = size * nitems;
auto str = (std::string*)userdata;
str->append(buffer, bytes);
To append data to buffer those things should be defined:
allowed size of destination buffer
amount of data in buffer present in destination buffer
amount of data to be copied to destination buffer
In C realloc() can be used to create new buffer with content of old one.. that may or may not change location of buffer. In C++ there is flavor of new operator that allows similar action.
If we assume that data stored is strictly null-terminated string (but even that wasn't specified!) then 2nd and 3rd are known - the size of buffer is unknown to append() is size of buffer. Therefore, the function
void append(void *y, char *z);
looks either unfit for the task or very unsafe and possibly ill-defined, unless void y is actually some structure or class (but passing that as void???) .
You did not provide implementation OR description of it. By the look is should be rather limited one. We should pre-allocate a buffer of proper size and ensure that append() won't run outside of its bounds. It cannot reallocate target buffer, so it is limited by already allocated memory. To actually reallocate target buffer append would have void **y or void &* y as formal parameter (realloc() may change pointer and does copy data from old buffer to new buffer)
This poses an architecture problem - ownership of buffer. If we pass buffer we control, we can allocate it properly and pass it to append() OR pass ownership to append() so it would reallocate it. If we don't, we have to create a temporal buffer... but can we use that temporal buffer afterwards?
The point is moot unless you are using custom header write function. user data pointer is CURLOPT_HEADERDATA, which is either pointer to valid FILE and you should _fwrite() data to it... Or, if you are implementing CURLOPT_WRITEFUNCTION and CURLOPT_READFUNCTION callback, that pointer can be used at discretion of designer of callbacks, as a pointer to some useful data container (libcurl uses fwrite as default callback).
Your question looks more referring to C (not C++) approach. Then you need the following:
know the size of the y
realloc the y to be of the size + 1
memcpy/memmove y to the new place
set the last byte of the new buffer to z
return to the user the pointer and the size of the new buffer
free the old buffer y (depends on the need).
In C++ hovewer you need to use some container like std::vector, which will allow you to append one byte.

Char passing to other function best practice

I want to pass string to second function where it fills the character array and gives the value back. In the first function I want to take the string length after second function fills it.
first step
Planning to pass the character array
char data[10]="";
GetData(data); // Here Iam doing memset value to data
strlen(data);
second step
Planning to pass the character pointer
char *data;
GetData(data); // what I should do
strlen(data);
Can someone suggest which is the best practice
You want to use std::string, something like:
std::string data;
void GetData(std::string& str);
passing by non-const reference allows GetData to alter str.
Ideally the character pointer should be owned by the caller, and should take care of allocation (if possible, or callee has to do that on behalf of the caller) and deallocation
char *data = (char *) NULL; // should initialize to know allocated or not
the prototype of the call, GetData should be:
void GetData(char *& d); // pointer passed as reference
Within GetData, d shoud be allocated as:
d = new char[size]; //size should be appropriately decided including null terminating character
for example, if you wish to store a "hello" say, d should be allocated as :
d = new char[5+1]; // example
once done, in the caller, you must deallocate as:
if (data) delete [] data;
data = (char *) NULL;
The "classic", C-compatible method in Windows (where Visual C++ is most used) is to have a function that takes the buffer size as argument, and returns the size or length of data copied. Example:
//Inputs:
// buffer: [out/opt] If not null, write data here.
// size: [in] Buffer size including null terminator, ignored if buffer is null.
//Outputs:
// buffer: The data.
// Return Value: Length of data written to the buffer, without null terminator.
int GetData(char *buffer, size_t bufferSize);
This allows calling the function with a null buffer to obtain the length to allocate, allocate the data, and call the function again.
However, it's not very C++ and it's error-prone. Passing a pointer/reference to the pointer to allocate is better from a language standpoint, but has its drawbacks when crossing a DLL boundary, where it's recommended that any data allocated by a DLL be deallocated by the same DLL (preventing the use of ordinary smart pointers).

Confusion with void* type memory allocation?

I am pretty inexperienced in C++ programming and now I'm trying to make a small program using dctmk to modify the pixel data of the dicom image. In doing so while reading documentation I found a c++ method about which I'm not quite clear. In the documention for the class DicomImage I found the following method:
int DicomImage::getOutputData ( void * buffer,
const unsigned long size,
const int bits = 0,
const unsigned long frame = 0,
const int planar = 0
)
My confusion is about buffer. It's quoted in the link as
buffer : pointer to memory buffer (must already be allocated)
Here my confusion is how do a I allocate? I'm not sure how I could allocate a memory that's a pointer of void type. Could you please explain. Thank you.
You can do it in the following way (for example):
void * mem = malloc(1024); // 1 kb
image.GetOutputData(mem, 1024);
// Don't forget to free(mem);
Another way:
char * mem = new char[1024];
image.GetOutputData((void *)mem, 1024);
// Don't forget to delete[] mem;
Another way:
char mem[1024];
image.GetOutputData((void *)&mem, 1024);
A pointer to void can point to anything, it's a generic nondescript anonymous pointer to some memory. This means that you can pass any kind of pointer as the first argument of the function, as all pointers can implicitly be converted to void*.
You can allocate any type of buffer. It will be converted using void*. However you will need to pass proper size of element. You will need to refer to documentation of api for size of each buffer element. In the example below it is 1 byte. And total buffer size is 10.
int size_of_buffer = 10;
unsigned char *buffer = malloc(sizeof(unsigned char)*size_of_buffer);
It looks like DicomImage::getOutputData does not care how you allocated your bytes. Simply take take the pointer to some blob of your choice (object, struct, array, whatever) and cast it to void*. You can get the memory with new, malloc or it can be a local variable.
Thing to be sure of:
Make sure you allocate enough space.
Make sure you accurately send the size parameter.
Make sure that you understand what format of data DicomImage::getOutputData works with.

Sending char ** data types to device

I have an array of character pointers which I want to send to device. Can somebody tell me how?
Here is what I have tried so far:
char **a;
char **b;
*a[0]="Foo1";
*a[1]=="Foo2";
cudaMalloc(void**)?,sizeof(?);
cudamemcpy(b,a,sizeof(?),cudaMemcpyHostToDevice);
How do I pass in the parameters to the above two functions?
And finally how should the kernel be called? (Do I just pass b or *b or something?)
If you send the character pointers to the device, you will have an array of CPU memory addresses on the device, which is probably not what you want.
If you want to send the whole data structure there, allocate sizeof(char) * string_length bytes for each string, and then store the resulting device pointers in a CPU array of char*s. Then, once it's complete, send the array of device pointers to the device, allocating sizeof(char*) * number_of_strings bytes for it.
When you call the kernel, give it the device-side array of device pointers.
to assign, use array[0] = "string literal"
No need for stars.
To get length, use strlen(). siezeof is irrelevant.
Never copy into this string matrix, or pass it as out parameter.
You have to allocate memory for that.