I am importing a mat file to my C++ code. After importing data, performing calculations and saving to another place I want to free the memory occupied by the original data.
Is there any specific function to perform that. Would just deleting the pointer returned by mxGetData() free the memory?
This is the class I have created to import mat file
#ifndef READMAT_H
#define READMAT_H
#include "mat.h"
#include "matrix.h"
#include "mex.h"
#include "program_exception.h"
#include "stdint.h"
class readmat
{
private:
const size_t *dimarray;
const char **dir;
MATFile *pmat;
int ndir;
mxArray *painfo,*pa;
const char *file;
int minute;
int second;
const char *name;
const char *name1;
bool isdouble;
no_mat_exception noMAT;
public:
//with default value
readmat(const char *f);
// get number of dimensions
int getnumbrofdimensions() const;
// get pointer to array
void* getarraypointer() const;
// get pointer to each dimension size
const size_t* dimensionpointer() const;
//number of elements
int numberofelements() const;
~readmat();
};
#endif
The following is the cpp implementation
#include "readmat.h"
#include <iostream>
#include "mat.h"
#include "matrix.h"
#include "mex.h"
using namespace std;
// set the file name
readmat::readmat(const char *f)
{
file = f;
pmat = matOpen(file, "r");
if (pmat == NULL) {
throw noMAT;
}
else
{
dir = (const char **)matGetDir(pmat, &ndir);
if (dir == NULL) {
printf("Error reading directory of file %s\n", file);
}
else if (ndir > 1)
{
cout << "The number of variables are larger than 1" << endl;
}
else
{
mxFree(dir);
matClose(pmat);
pmat = matOpen(file, "r");
if (pmat == NULL) {
throw noMAT;
}
else
{
painfo = matGetNextVariableInfo(pmat, &name);
matClose(pmat);
}
pmat = matOpen(file, "r");
if (pmat == NULL) {
throw noMAT;
}
else
{
pa = matGetNextVariable(pmat, &name1);
matClose(pmat);
}
}
}
}
int readmat::getnumbrofdimensions() const
{
return mxGetNumberOfDimensions(painfo);
}
void* readmat::getarraypointer() const
{
//return mxGetPr(pa);
return mxGetData(pa);
}
const size_t* readmat::dimensionpointer() const
{
return mxGetDimensions(painfo);
}
int readmat::numberofelements() const
{
return mxGetNumberOfElements(painfo);
}
readmat::~readmat()
{
mxFree(pa);
mxFree(painfo);
}
Here when I delete the object program trigger a break point in the file free.c.
The MATLAB demo on edit([matlabroot '/extern/examples/eng_mat/matdgns.c']); seems to suggest using mxDestroyArray instead of mxFree.
When calling mxGetData(). The only thing the function does, is returning a pointer to the real (in contrast to imaginary) data that is stored in the mxArray.
So there is no need to free memory, since nothing is dynamically allocated during this call.
Related
I have a class in C++ that represents a buffer where I can store unsigned char. I have two methods, one the add generic values using templates and another to retrieve the values. When I am trying to retrieve the values I am getting Segmentation fault (core dumped). I am using memcpy If I change to use std::copy(value, value, _valueChar); I get other errors: error: no type named ‘value_type’ in ‘struct std::iterator_traits<int>’
#include <iostream>
#include <cstring>
#include <utility>
#include <vector>
#include <string>
class SkinnyBuffer {
private:
unsigned char *_valueChar;
std::size_t _sizeChar;
public:
SkinnyBuffer();
SkinnyBuffer(std::size_t size);
~SkinnyBuffer();
void clean();
template<typename T>
void addValue(T value) {
if (_valueChar != nullptr) {
delete[] _valueChar;
}
// _sizeChar = n; // assume _size is a field
// _valueChar = new unsigned char[_sizeChar];
// std::copy(value, value, _valueChar);
memcpy(_valueChar, &value, sizeof(value));
}
template<typename T>
void addValue(std::size_t offset, T value) {
if (_valueChar != nullptr) {
delete[] _valueChar;
}
// _sizeChar = n; // assume _size is a field
// _valueChar = new unsigned char[_sizeChar];
// std::copy(value, value + offset, _valueChar);
memcpy(_valueChar + offset, &value, sizeof(value));
}
unsigned char *getValue() {
return _valueChar;
}
};
#include "SkinnyBuffer.h"
SkinnyBuffer::SkinnyBuffer() {
}
SkinnyBuffer::SkinnyBuffer(std::size_t size) {
_sizeChar = size;
_valueChar = new unsigned char[_sizeChar];
}
SkinnyBuffer::~SkinnyBuffer() {
}
void SkinnyBuffer::clean() {
_valueChar = new unsigned char[_sizeChar];
}
int main(int argc, char *argv[]) {
int value = 50;
int offset = sizeof(value);
SkinnyBuffer b(offset);
b.addValue(value);
int dValue;
memcpy(&dValue, b.getValue(), offset);
std::cout << dValue << std::endl;
}
In addValue you explicitly delete the _valueChar buffer. Then the next line along you write into the deleted buffer. What did you expect this code to do?
This is the first of many issues in your code regarding memory management.
Just use a std::vector and as long as its big enough you wont have any of those issues.
I am writing a C++ program (see below). My goal is to store data in iov struct. I have allocated buffer of fixed length in constructor. Every time that buffer gets filled, I want to transfer data in iov and allocated new buffer of fixed length. Finally when done with data processing, I want to return iov struct. My intension here is to store all these data into iov so that if it's required in future, I can send data easily. I have written sample code. But it seems it's not working. I got an "Bus error: 10". Can someone help me?
Sample code:
#include <iostream>
#include <string>
#include <sys/uio.h>
#include <cstdlib>
using namespace std;
#define MAX_LEN 1000
#define MIN_LEN 20
class MyClass
{
public:
MyClass();
~MyClass();
void fillData(std::string &data);
private:
struct iovec *iov;
unsigned int count;
unsigned int len;
char *buf;
unsigned int total_len;
unsigned int tmp_len;
};
MyClass::MyClass()
{
cout << "Inside constructor" << endl;
total_len = MIN_LEN;
buf = (char *)malloc(MAX_LEN);
if (buf == NULL) {
cout << "Error: can’t allocate buf" << endl;
exit(EXIT_FAILURE);
}
}
MyClass::~MyClass()
{
free(buf);
}
void MyClass::fillData(std::string &data)
{
unsigned int d_len, tmp_len, offset;
d_len = data.size();
const char* t = data.c_str();
total_len += d_len;
tmp_len += d_len;
if (total_len > MAX_LEN) {
/* Allocate memory and assign to iov */
tmp_len = d_len;
}
memcpy(buf + offset, t, d_len);
/* Adjust offset */
}
int main()
{
MyClass my_obj;
int i;
std::string str = "Hey, welcome to my first class!";
for (i = 0; i < 10; i++) {
my_obj.fillData(str);
}
return 0;
}
Without understanding the intent of your program in detail, it is very clear that you forgot to reserve memory for the iov-objects themselfes.
For example, in your constructor you write iov[0].iov_base = buf, yet iov has not been allocated before.
To overcome this, somewhere in your code, before the first access to iov, you should write something like iov = calloc(100,sizeof(struct iovev)) or a c++ equivalent using new[].
Consider the following program:
struct myStruct {
char *buf;
int len;
};
int main() {
struct myStruct *myStructPtr;
myStructPtr->buf = "Herbert"; // Illegal, since myStructPtr is not initialized; So even if "Herbert" is valid, there is no place to store the pointer to literal "Herbert".
myStructPtr[0].buf = "Herbert"; // Illegal, since myStructPtr is not initialized
// but:
struct myStruct *myStructObj = new (struct myStruct);
myStructObj->buf = "Herbert"; // OK, because myStructObj can store the pointer to literal "Herbert"
myStructObj->buf = "Something else"; // OK; myStructObj can hold a pointer, so just let it point to a different portion of memory. No need for an extra "new (struct myStruct)" here
}
I took your code, which didn't exactly use anything with the iovec, and I modified it a little.
I am not sure why developers prefer buffers of char* instead of std::string
or why use a pointer which should be allocated and then deleted instead of using a std::vector
I also added a function which uses the iovec. It is called void MyClass::print_data(). It prints all the data in the vector iovecs
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
#include <vector>
#include <unistd.h>
#include <sys/uio.h>
using namespace std;
class MyClass
{
vector<struct iovec> iovs;
vector<string> bufs;
public:
MyClass();
~MyClass();
void fill_data(const string &data);
void print_data();
};
MyClass::MyClass()
{
cout << "Inside constructor" << endl;
}
MyClass::~MyClass()
{
}
void MyClass::fill_data(const string &data)
{
stringstream stream;
stream << setw(2) << setfill(' ') << (this->bufs.size() + 1) << ". "
<< data << endl;
this->bufs.push_back(stream.str());
iovec iov = {&(bufs.back()[0]), bufs.back().size()};
this->iovs.push_back(iov);
}
void MyClass::print_data() {
writev(STDOUT_FILENO, iovs.data(), iovs.size());
}
int main() {
MyClass my_obj;
string str = "Hey, welcome to my first class!";
for (int i = 0; i < 10; ++i) {
my_obj.fill_data(str);
}
my_obj.print_data();
return 0;
}
compile it like so: g++ test.cpp
I want to implement class in way that different processes can access the same static data:
class Shared()
{
public:
static int GetValue();
static void SetValue(int value);
};
How to do this using shared memory to store internal data. Could anyone help me to do this? Any answer will be appreciated.
Sample code is as shown below, this is a very basic implementation. Class will explain how to create, set/get single value and destroy shared memory. Error checks, notifications etc can be added as policy classes using templates.
#include <iostream>
#include <stdexcept>
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <string.h>
template <key_t KEY, typename T, int COUNT = 1>
class Shm
{
public:
Shm():shm_(0)
{
get();
attach();
}
~Shm()
{
if(shm_ != NULL)
{
shmdt(shm_);
shm_ = 0;
}
}
//Set one element
void SetValue(const T* data, int count = 1)
{
if(sizeof(T)*count > sizeof(T) * COUNT)
{
throw std::runtime_error("Data size greater than shm size");
}
memcpy(shm_, data, sizeof(T)*count);
}
//Get pointer to element
const T* GetValue()
{
T* ptr = new(shm_) T;
return ptr;
}
static void create()
{
if ((shmid_ = shmget(KEY, COUNT*sizeof(T), IPC_CREAT | 0666)) < 0)
{
throw std::runtime_error("Failed create shm");
}
}
static void destroy()
{
get();
if(shmctl(shmid_, IPC_RMID, NULL)<0)
{
perror("shctl");
throw std::runtime_error("Error cannot remove shared memory");
}
shmid_ = -1;
}
private:
static void get()
{
if(shmid_ == -1)
{
if((shmid_ = shmget(KEY, COUNT*sizeof(T), 0666)) < 0)
{
perror("shmget");
throw std::runtime_error("Shared memory not created");
}
}
}
void attach()
{
if ((shm_ = shmat(shmid_, NULL, 0)) == (char *) -1)
{
throw std::runtime_error("Failed attach shm");
}
}
void* shm_;
static int shmid_;
};
template <key_t KEY, typename T, int COUNT>
int Shm<KEY, T, COUNT>::shmid_ = -1;
int main(int argc, char ** argv)
{
if(argc == 2)
{
if(std::string(argv[1]) == "server")
{
int val = 50;
Shm<0x1234, int>::create();
Shm<0x1234, int> shm;
shm.SetValue(&val);
}
else if(std::string(argv[1]) == "client")
{
Shm<0x1234, int> shm;
const int* ptr = shm.GetValue();
std::cout <<"Val = " << *ptr <<std::endl;
Shm<0x1234, int>::destroy();
}
}
else
{
std::cerr<<"Usage shm [server][client]"<<std::endl;
}
return 0;
}
You really don't want to hand-roll a solution for this (specially if it has to be portable), but fortunately boost::interprocess that will give such features and more (e.g. allocators) for shared memory.
Minimal example (untested):
#include <boost/interprocess/managed_shared_memory.hpp>
using namespace boost::interprocess;
void* allocate(size_t bytes)
{
static managed_shared_memory segment(create_only, "MySharedMemory", 65536);
return segment.allocate(bytes);
}
Is there a way to apply the shader in plugin?
I'm trying to implement anti-aliasing, but all my attempts failed :\
Use this simple:
#include <fstream>
#include <sstream>
#include "DDImage/Knobs.h"
#include "DDImage/DDMath.h"
#include "DDImage/ViewerContext.h"
#include "DDImage/Iop.h"
#include "DDImage/PixelIop.h"
#include "DDImage/Row.h"
using namespace DD::Image;
////////////////////////////////////////////////////////////////
/// GPU File Shader Op.
class GPUFileShader : public DD::Image::PixelIop
{
const char* shaderFile_;
std::string currShaderFile_;
std::string shader_;
int version_;
int currVersion_;
const char* gpuEngine_body() const
{
return shader_.c_str();
}
void pixel_engine(const Row& in, int y, int x, int r, ChannelMask channels, Row& out)
{
foreach(z, channels) {
const float* inptr = in[z] + x;
const float* END = inptr + (r - x);
float* outptr = out.writable(z) + x;
while (inptr < END)
*outptr++ = *inptr++;
}
}
void in_channels(int, DD::Image::ChannelSet& c) const { } // return c unchanged
public:
GPUFileShader(Node* node)
: PixelIop(node)
, shaderFile_(0)
, version_(0)
, currVersion_(0)
{ }
void knobs(Knob_Callback f)
{
File_knob(f, &shaderFile_, "shader_file", "OpenGL Shading Language file");
}
void _validate(bool)
{
if (!shaderFile_)
return;
if (version_ != currVersion_ || currShaderFile_ != std::string(shaderFile_)) {
std::ifstream ifs(shaderFile_);
if (!ifs) {
Iop::error("Error reading shader file.");
return;
}
std::stringstream str;
std::copy(std::istreambuf_iterator<char>(ifs), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(str));
shader_ = str.str();
currVersion_ = version_;
currShaderFile_.assign(shaderFile_);
}
copy_info(0);
}
static const DD::Image::Op::Description d;
const char* Class() const { return d.name; }
const char* node_help() const { return "GPU Op which gets initialised from a file. Customise for proprietary formats. Default assumes OpenGL shading language code."; }
};
static Op* GPUFileShader_c(Node* node) { return new GPUFileShader(node); }
const Op::Description GPUFileShader::d("GPUFileShader", GPUFileShader_c);
I have a problem. When I compile the program I don't have any errors, but when I use valgrind:
Uninitialized value was created by a heap allocation (line with new)
Conditional jump or move depends on uninitialized value(s)(line with delete)
I search through the forums however I didn't find much information which could help me.
I would be really grateful for a hint.
My program
#include <cstdlib>
#include <stdint.h>
#include <cstdio>
#include <iostream>
#include <string>
#include <istream>
#include <cstring>
#include <fstream>
#include <sstream>
#include <cctype>
using namespace std;
using std::cout;
using std::endl;
int dlugosc,miejsce;
ifstream file;
class channel
{
public:
int start;
double length;
int bytespix;
int resolution;
channel(double g) : start(g),
length(0),
bytespix(0),
resolution(0)
{
}
};
int fileopen() // opens the file and returns its size
{
file.open ("0_dlc.000", ios::in|ios::binary);
if( file.good() == true )
{
cout << "Uzyskano dostep do pliku!" << endl;
}
else
{
cout<< "File cannot open" <<endl;
}
file.seekg(0, file.end);
dlugosc = file.tellg();
return dlugosc;
}
int findword(const char* slowo,int startplace)
{
int m;
int c=0;
int cur=0;
unsigned int equal=0;
char element=0;
file.seekg (startplace, file.beg);
for(m=0;m<dlugosc;m++)
{
file.get(element);
if(element==slowo[cur])
{
equal++;
cur++;
}
else
{
equal=0;
cur=0;
if(element==slowo[cur])
{
equal++;
cur++;
}
}
if(equal==strlen(slowo))
{
return m+startplace;
}
}
return 0;
}
int findvalue(const char* wartosc,int startpoint)
{
int p;
int g;
char element=0;
char* buffer = new char[9];
miejsce = findword(wartosc,startpoint); // miejsce to global variable
file.seekg (miejsce+1, file.beg);
for(p=0;(int)element<58;p++)
{
file.get(element);
if((int)element>58 || (int)element<48)
break;
else
buffer[p] = element;
}
buffer[p]='\0';
g = atoi(buffer);
delete [] buffer;
return g;
}
int main()
{
int a,h=0,channels,start=0,length=0,resolution=0,bytespix=0,m=0;
const char* slowko="Data offset: ";
dlugosc=fileopen();
channel** kanaly=0;
kanaly = new channel*[9];
miejsce=0;
for(a=0;a<9;a++)
{
kanaly[a] = new channel(4);
start = findvalue("Data offset: ",miejsce+20);
kanaly[a]->start=start;
}
for(m=0;m<9;m++)
{
delete kanaly[m];
}
delete []kanaly;
file.close();
}
The problem is in the constructor of channel. Initialize all member variables, and the problem will go away :
class channel
{
public:
double start;
double length;
int bytespix;
int resolution;
channel(double g) : start(g),
length(0),
bytespix(0),
resolution(0)
{
}
};