I wrote a mexfunction on c++ code, then compiled it to get mexa64 file. After I used mexa64 file for many times, my PC memory run out.
Here is my mexfunction:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
// double *res ;// the final result index
int status1,status2,status3;
double *res ;
double *out_mat;
double *x_idx,*y_idx,*width_idx,*height_idx;
char* sequence_path;// the tracking image sequences
char* sequence_name;// the tracking image sequences
char* output_path;// save the output
int start_frame=(int)mxGetScalar(prhs[0]);
int end_frame=(int)mxGetScalar(prhs[1]);
int Max_track_number=(int)mxGetScalar(prhs[2]);
/* Extract the inputs */
int buflen1=(mxGetM(prhs[3])*mxGetN(prhs[3]))+1;
sequence_path= (char *)mxCalloc(buflen1,sizeof(char));
status1=mxGetString(prhs[3],sequence_path,buflen1);
int buflen2=(mxGetM(prhs[4])*mxGetN(prhs[4]))+1;
sequence_name= (char *)mxCalloc(buflen2,sizeof(char));
status2=mxGetString(prhs[4],sequence_name,buflen2);
int buflen3=(mxGetM(prhs[5])*mxGetN(prhs[5]))+1;
output_path= (char *)mxCalloc(buflen3,sizeof(char));
status3=mxGetString(prhs[5],output_path,buflen3);
if(status3!=0)
mexWarnMsgTxt("Not enough space. String is truncated.");
float x=(float)mxGetScalar(prhs[6]);
float y=(float)mxGetScalar(prhs[7]);
float width=(float)mxGetScalar(prhs[8]);
float height=(float)mxGetScalar(prhs[9]);
x_idx=mxGetPr(prhs[6]);
y_idx=mxGetPr(prhs[7]);
width_idx=mxGetPr(prhs[8]);
height_idx=mxGetPr(prhs[9]);
mexPrintf("the dimension is %f,%f,%f,%f\n",*x_idx,*y_idx,*width_idx,*height_idx);
int N1=mxGetM(prhs[6])*mxGetN(prhs[6]);
int N2=mxGetM(prhs[7])*mxGetN(prhs[7]);
int N3=mxGetM(prhs[8])*mxGetN(prhs[8]);
int N4=mxGetM(prhs[9])*mxGetN(prhs[9]);
if(N1!=N2|N2!=N3|N3!=N4)
mexErrMsgTxt("the dimension of the initial bounding box parameter is wrong");
int NN=N1;
plhs[0] = mxCreateDoubleMatrix(Max_track_number*5*NN,1,mxREAL);
out_mat = mxGetPr(plhs[0]);
plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
res = mxGetPr(plhs[1]);
*res=struck_track(start_frame,end_frame,Max_track_number,sequence_path,sequence_name,output_path,out_mat,x_idx,y_idx,width_idx,height_idx,NN);
}
Is there some problems that may cause the exhaustion of memory?
you should use mxFree whenever using the following:
mxCalloc
mxMalloc
mxRealloc
mxArrayToString
I can see from your code that you are using mxCalloc but there is no corresponding mxFree for the same.
Besides using mxFree you can also increase the Java Heap Size. You can find it under settings, general, java heap memory.
Related
I would like to pass a String vector into an external C function.
In a minimal example I just want to pass the String vectors (or 1D array) through the C function.
My Modelica function looks like:
function testreadstri
input String instri[2];
output String outstri[2];
external "C" test_stri(instri,, size(instri, 1), outstri);
annotation (Include="#include <ebcmysql.cpp>", Library="libmysql");
end testreadstri;
My C fucntion looks like:
void test_stri(const char* thestring, size_t nLines, const char **testresult)
{
//bout = 12.3;
size_t iLines;
//size_t nLines;
iLines = 0;
//nLines = 1;
while ( iLines <= nLines ) {
<LINE_OF_INTEREST>
iLines++;
}
}
I tried for <LINE_OF_INTEREST> the following lines:
testresult[iLines] = thestring[iLines];
strcpy(testresult[iLines], thestring[iLines]);
What works, but of course does not pass the input through as an output, is:
testresult[iLines] = "aTestString";
Is there any possibility to handle Modelica input String vectors in the external C function?
Thanks in advance!
Here's a short, self-contained and compilable example demonstrating both input string and output string handling of a pure external function in Modelica
model Model
function testreadstri
input String instri[2];
output String outstri[2];
external "C" test_stri(instri, size(instri, 1), outstri, size(outstri, 1));
annotation(Include="
#include \"ModelicaUtilities.h\"
#include <stdlib.h>
#include <string.h>
void test_stri(const char** thestring, size_t nLinesIn, const char** testresult, size_t nLinesOut)
{
size_t iLines;
// example for input string handling
for (iLines = 0; iLines < nLinesIn; iLines++) {
ModelicaFormatMessage(\"%s\\n\", thestring[iLines]);
}
// example for output string handling
for (iLines = 0; iLines < nLinesOut; iLines++) {
char* line = ModelicaAllocateStringWithErrorReturn(6);
if (line != NULL) {
strcpy(line, \"result\");
testresult[iLines] = line;
}
}
}");
end testreadstri;
String s[:] = testreadstri({"first", "second"});
end Model;
Yes, this is supported by the Modelica specification, see https://specification.modelica.org/v3.4/Ch12.html#argument-type-mapping.
I am trying to write uint64_t(double word) variable into the flash memory, without success though. Here is the code.
#define APPLICATION_START_ADDRESS 0x8008000
void flashErase(uint8_t startSector, uint8_t numberOfSectors)
{
HAL_FLASH_Unlock();
Flash_eraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
Flash_eraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
Flash_eraseInitStruct.Sector = startSector;
Flash_eraseInitStruct.NbSectors = numberOfSectors;
if(HAL_FLASHEx_Erase(&Flash_eraseInitStruct, &Flash_halOperationSectorError) != HAL_OK)
{
Flash_raiseError(errHAL_FLASHEx_Erase);
}
HAL_FLASH_Lock();
}
int main(void)
{
HAL_Init();
main_clockSystemInit();
__IO uint64_t word = 0x1234567890;
flashErase(2, 1);
// flashProgramWord(aTxBuffer, APPLICATION_START_ADDRESS, 2 );
HAL_FLASH_Unlock();
HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, APPLICATION_START_ADDRESS, word);
}
I get error flag raised PGSERR and PGAERR. The erase operation goes without problems. But programming returns ERROR.
Some Ideas?
There is no STM32F249, did you mean STM32F429?
In order to use 64 bit programming, VPP (BOOT0) has to be powered by 8 - 9 Volts. Is it?
See the Reference Manual Section 3.6.2
By the way,
__IO uint64_t word = 0x1234567890;
would not work as (presumably) expected. It is a 32 bit architecture, integer constants will be truncated to 32 bits, unless there is an L suffix. U wouldn't hurt either, because the variable is unsigned. __IO is unnecessary.
uint64_t word = 0x1234567890UL;
I have a program in AVR Studio V4 with the following code:
#include <avr/pgmspace.h>
void nlcd_Putc(unsigned char c)
{
unsigned char i;
if (c>127) c=c-64;
for (i = 0; i < 5; i++ )
{
nlcd_SendByte(DATA_LCD_MODE,pgm_read_byte(&(nlcd_Font[c-32][i])));
}
nlcd_SendByte(DATA_LCD_MODE,0x00);
}
So when i want to run this code in MiKroC for AVR i get the following error:
128 324 Undeclared identifier 'pgm_read_byte' in expression MyProject.c
Should I add the header avr/pgmspace.h To MiKroc For AVR, or what is the equivalent header to avr/pgmspace.h in Mikroc For AVR?
Thanks a lot.
by addinf this codes to header :
typedef signed char int8;
typedef unsigned char uint8;
typedef signed int int16;
typedef unsigned int uint16;
typedef signed long int int32;
typedef unsigned long int uint32;
//-----------------------
#define PGM_P char flash *
#define PROGMEM flash
#define const flash
#define PSTR(x) x
#define EEMEM eeprom
#define pgm_read_byte(x) (*((uint8 flash *)(x)))
#define pgm_read_word(x) (*((uint16 flash *)(x)))
#define pgm_read_float(x) (*((uint32 flash *)(x)))
#define pgm_read_byte_near(x) (*((uint8 flash *)(x)))
I have an XSUB like this:
char *
string4()
CODE:
char *str = strdup("Hello World4");
int len = strlen(str) + 1;
New(0, RETVAL, len, char);
Copy(str, RETVAL, len, char);
free(str);
OUTPUT:
RETVAL
But this shows up as a memory leak, on the New(), in valgrind and if I run it in a loop the resident memory will continue to grow.
I get the same thing if I use this one too:
char *
string2()
CODE:
char *str = strdup("Hello World2");
RETVAL = str;
OUTPUT:
RETVAL
I'm able to prevent the leak and the increasing memory size by doing:
char *
string3()
PPCODE:
char *str = strdup("Hello World3");
XPUSHs(sv_2mortal(newSVpv(str, 0)));
free(str);
but the problem with this solution is that when I compile with -Werror I get the following warnings/errors.
test.c: In function ‘XS_test_string3’:
/usr/lib/x86_64-linux-gnu/perl/5.20/CORE/XSUB.h:175:28: error: unused variable ‘targ’ [-Werror=unused-variable]
#define dXSTARG SV * const targ = ((PL_op->op_private & OPpENTERSUB_HASTARG) \
^
test.c:270:2: note: in expansion of macro ‘dXSTARG’
dXSTARG;
^
test.c:269:9: error: unused variable ‘RETVAL’ [-Werror=unused-variable]
char * RETVAL;
the c file gets built with an unused RETVAL:
XS_EUPXS(XS_test_string3); /* prototype to pass -Wmissing-prototypes */
XS_EUPXS(XS_test_string3)
{
dVAR; dXSARGS;
if (items != 0)
croak_xs_usage(cv, "");
PERL_UNUSED_VAR(ax); /* -Wall */
SP -= items;
{
char * RETVAL;
dXSTARG;
#line 61 "test.xs"
char *str = strdup("Hello World3");
XPUSHs(sv_2mortal(newSVpv(str, 0)));
free(str);
#line 276 "test.c"
PUTBACK;
return;
}
}
So is there a better way to handle the returning of allocated strings in XS? Is there a way to return the string using RETVAL and free the memory? I appreciate any help.
Among other problems[1], your first snippet allocates memory using New, but never deallocates it.
Among other problems, your second snippet allocates memory using strdup, but never deallocates it.
The underlying problem with your third snippet is that you claim the XS function returns a value and it doesn't. That value would have been assigned to RETVAL, which is automatically created for that very purpose. The variable won't be created if you correctly specify that you don't return anything.
void
string3()
PREINIT:
char *str;
PPCODE:
str = strdup("Hello World3");
XPUSHs(sv_2mortal(newSVpv(str, 0)));
free(str);
or just
void
string3()
PPCODE:
XPUSHs(sv_2mortal(newSVpv("Hello World3", 0)));
Note that I moved your declarations out of PPCODE. In C, declarations can't appear after non-declarations, and the code in PPCODE can appear after non-declarations (depending on the options used to build Perl). Declarations belong in PREINIT. You could also use curlies around the code in PPCODE.
One of them is the use of New. You shoudln't be using New. New was deprecated in favour of Newx ages ago. New hasn't even been in the documentation for as long as I can remember.
I have a MEX function and I need to get the name of the function which called this MEX function from Matlab. Is there a way how to do it?
I have tried
mexCallMatlab(...,"dbstack")
but, it returns an empty result, because it is probably run in the workspace.
Yes, I know I could pass the function name directly as an argument, but that is not an option for me.
Calling "dbstack" using "mexCallMATLAB" from within the MEX function should do the trick. Just need to be a little careful when converting the output of "dbstack", which is a MATLAB struct, into a string. This is the C MEX code
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs,
const mxArray *prhs[]) {
mxArray *mxArr[1];
mexCallMATLAB(1, mxArr, 0, NULL, "dbstack");
char *funcName = mxArrayToString(mxGetField(mxArr[0], 0, "name"));
printf("Function name = %s\n", funcName);
}
This is the MATLAB function calling the MEX function.
function callMyMex()
myMex();
end
When you run the "callMyMex" function, you should see the output:
Function name = callMyMex
If you run dbstack in the base workspace, the struct will indeed be empty. Here's how I tested it using mexCallMATLAB:
testMEX.cpp
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
mxArray *dbStruct;
mexCallMATLAB(1, &dbStruct, 0, NULL, "dbstack");
plhs[0] = mxDuplicateArray(dbStruct);
if (mxIsEmpty(dbStruct) || mxGetNumberOfFields(dbStruct) != 3) {
mexErrMsgTxt("dbstack not available from base workspace");
return;
}
mxArray *callerFileName = mxGetField(dbStruct, 0, "file");
char *fileStr = mxArrayToString(callerFileName);
mxArray *callerFunctionName = mxGetField(dbStruct, 0, "name");
char *funStr = mxArrayToString(callerFunctionName);
mxArray *callerLineNum = mxGetField(dbStruct, 0, "line");
int lineNum = static_cast<int>(mxGetScalar(callerLineNum));
mexPrintf("File: %s\n",fileStr); mxFree(fileStr);
mexPrintf("Function: %s\n", funStr); mxFree(funStr);
mexPrintf("Line: %d\n", lineNum);
}
testFun.m
function s = testFun()
s = testMEX;
Output
>> s = testMEX
Error using testMEX
dbstack not available from base workspace
>> s = testFun
File: testFun.m
Function: testFun
Line: 3
s =
file: 'testFun.m'
name: 'testFun'
line: 3