Specifying the pointer when copying with OpenCV - c++

I'm having an image memory that I stocked and saved it in a pointer to not loose its address.
I would like now to assign it to an IplImage by the following function memcpy (what I have tested):
IplImage* img=cvCreateImage(cvSize(640, 480), IPL_DEPTH_16U, 1);
VOID* ImgMem;
memcpy(img->imageData, ImgMemory, (640*480));
It really doesn't work. It stated Unhandled exception at 0x001b96dd in ex4.exe: 0xC0000005: Access violation reading location 0x00000044.
Any idea how to deal with that?

Your image is 640x480, but you copied 916x916 pixals.

There are two problems in your code. The first issue is you are not initializing 'ImgMem'.
VOID* ImgMem;
// ^^^^^^ Points to whatever
If you need to use a buffer prior to copying the data to the image buffer you need to allocate memory for it.
int bufferSize = 640*480*2;
char* ImgMem = new char[bufferSize];
Make sure that you delete the memory once you are done with it or you will end up leaking memory.
delete[] ImgMem;
A better alternative would be to use std::vector;
std::vector<char> ImgMem(bufferSize, 0);
memcpy(img->imageData, &ImgMem[0], ImgMem.size());
This way the memory is allocated, managed and freed by std::vector instead of you having to do it every time.
The second problem is you are trying to copy more memory into the image buffer than it can hold.
memcpy(img->imageData, ImgMemory, (916*916));
This will copy 839,056 bytes when img->imageData can only hold 307,200 bytes (assuming 8bpp).
[Edit: This answer does not take into account the attributes provided by the IplImage structure. This includes size AND alignment which are fairly important here in regards to memcpy. For more information on members of IplImage see here]

pixel type is unsigned short IPL_DEPTH_16U and it is 2 bytes, therefore you need to calculate total byte size accordingly:
int totalSize = 640*480*2;
char* ImgMemory = new char[totalSize];
memcpy(img->imageData, ImgMemory, (totalSize ));

Related

Copying a MAT image to specific address in c++

I'm trying to copy a MAT image loaded in from a file to a specific address location. I have the following code
int main()
{
cv::Mat inImg = cv::imread("M6_traffic.jpg");
//Data point copy
unsigned char * pData = (unsigned char *)inImg.data;
unsigned char * Dest = (unsigned char *)0x0f000000;;
int width = inImg.rows;
int height = inImg.cols;
//data copy using memcpy function
memcpy(Dest, pData, sizeof(unsigned char)*width*height*3);
}
But when I run this it always crashes, any idea why? and is there a better why to do this? My end goal is to able to copy a image data to specific address in a Linux based system
propably there is no allocated memory on address 0x0f000000.
and you cannot force this to be a valid address
Allocate the right size of memory with malloc and it will work.
The OS then determines your address space and returns a pointer to it.
unsigned char* Dest = malloc(sizeof(pData));
memcpy(Dest, pData, sizeof(pData))
0x0f000000 is essentially a null pointer. What you're trying to do is copy data into a memory address that has not been set with memcpy(Dest, pData, sizeof(unsigned char)*width*height*3);.
You should allocate memory for Dest before your memcpy statement. You can do this with either malloc or calloc. These function calls are described in the following links. Hope this helps!
http://en.cppreference.com/w/c/memory/malloc
http://www.cplusplus.com/reference/cstdlib/calloc/

Memory Managing QByteArray::fromRawData()

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..

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.

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.

Determining the correct size for a C++ array

I need to be able to set the size of an array based on the number of bytes in a file.
For example, I want to do this:
// Obtain the file size.
fseek (fp, 0, SEEK_END);
size_t file_size = ftell(fp);
rewind(fp);
// Create the buffer to hold the file contents.
char buff[file_size];
However, I get a compile time error saying that the size of the buffer has to be a constant.
How can I accomplish this?
Use a vector.
std::vector<char> buff(file_size);
The entire vector is filled with '\0' first, automatically. But the performance "lost" might not be noticable. It's certainly safer and more comfortable. Then access it like a usual array. You may even pass the pointer to the data to legacy C functions
legacy(&buff[0]); // valid!
You should use a std::vector and not an array.
Real arrays require you to specify their size so that the compiler can create some space for them -- this is why the compiler complains when you don't supply a constant integer. Dynamic arrays are represented by a pointer to the base of the array -- and you have to retrieve the memory for the dynamic array yourself. You may then use the pointer with subscript notation. e.g.,
int * x;
x = (int *) malloc( sizeof(int) *
getAmountOfArrayElements() /* non-const result*/
);
x[5] = 10;
This leads to two types of problems:
Buffer over/under flows : you might subscript-index past either end of the array.
You might forget to release the memory.
Vector provides a nice little interface to hide these problems from you -- if used correctly.
Replace
char buff[file_size];
with
char *buff = new char[file_size];
and once the use of the buff is done..you can free the memory using:
delete[] buff;
There are two points in your question I'd like to cover.
The actual question, how do you create the array. Johannes answered this. You use a std::vector and create it with a size allocation.
Your error message. When you declare an array of some type, you must declare it with a constant size. So for example
const int FileSize = 1000;
// stuff
char buffer[FileSize];
is perfectly legitimate.
On the other hand, what you did, attempting to declare an array with variable size, and then not allocating with new, generates an error.
Problem is that buff needs be created on the heap (instead of stack). Compiler want s to know the exact size to create on the stack.
char* buff = new char[file_size];