LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

dynamic memory corrupt when executing Ini_ReadFromFile()

Hi Roberto,

I just cannot solve the same problem on the way how you describe.
I do the following in a function:

1. Declaring local variables (char type pointers to store strings temporary)
2. Ini_New()
3. Reading data from Inifile with Ini_Getxxx()
4. Ini_Dispose()
5. free all temporary strings - I think it is not necessary, as they are locals, so at the next call they must be new initialized.

At the second time, when I call this function, I get the "Dynamic memory corrupt" message.
By the way, I tried to use this: free(IniFile), and it works. What does Ini_Dispose() do???

regards
MB
0 Kudos
Message 11 of 16
(1,863 Views)

Hi MB,

How are you filling the IniText? Are you using Ini_ReadFromFile, Ini_ReadFromRegistry or Ini_ReadGeneric to put label/value pairs into it? Could you post the code of your function so that we can examine it and make some simulation?

 

Regarding your second question, a IniFile pointer can be freed by free () function, but as you can see examining the source code of Ini_Dispose, there are several additional resources that must be deallocated and freed before the struct can be discarded. Source code of the function is available in toolbox directory the same as IniFile.fp instrument.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 12 of 16
(1,853 Views)
Hi Roberto,

yes I already opened the infile.c, I see what happens. But I still don´t understand what I do wrong. It works for the first time, the second time never. I have read the linked knowledge base, wha dynamic memory corrupts. I haven´t found the solution.

Thanksk for your help in advance

int LoadTestPlan (char *barcode){
char tpPath[100];
char str[100];
char *tagName;
char *tagStrVal;
int index=0;
int error=0;
char error_string[256];
int NrOfSections, NrOfItems, NrOfTeststeps;
int items = 0;
char *sectionNamePtr;
int i=0, j=0, x=0, y=0;
int Table_NrOfRows, Table_NrOfColumns;
double n;
char **TableArray;
IniText tpFile=0;

strcpy(type, barcode);
type[13] = 0; // get the first 13 characters from barcode as type
strcat(type, ".ini");
SetCtrlVal(fp_dbg, FP_DBG_SECTION_NAME, type);
strcpy(tpPath, gTpFilePath);
strcat(tpPath, type);
if(!(tpFile = Ini_New(0))){
MessagePopup("Inifile","Error allocating memory for Inifile");
return 0;
}
if(error = Ini_ReadFromFile(tpFile, tpPath)){
if(-999<=error<=-1) strcpy(error_string, GetUILErrorString(error));
if(-5000>=error>=-5999) strcpy(error_string, GetToolboxErrorString(error));
MessagePopup("Error at opening testplan", error_string);
return 0;
}

/* Get Number of Sections */
NrOfTeststeps = Ini_NumberOfSections(tpFile) - 1; // First section is the HEADER

// allocate memory for array of struct
gTestSteps = (TestType **)malloc( NrOfTeststeps * sizeof(*gTestSteps)); // allocate mem for 200 test steps
for(i=0; i gTestSteps[i] = (TestType *)malloc(sizeof(TestType)); // new struct
}

sectionNamePtr = (char *)malloc(256);
sectionNamePtr = "HEADER";

NrOfItems = Ini_NumberOfItems(tpFile, sectionNamePtr); // Get HEADER Items
for(i=0; i Ini_NthItemName(tpFile, sectionNamePtr, i+1, &tagName);
Ini_GetPointerToString(tpFile, sectionNamePtr, tagName, &tagStrVal);
if(!(strcmp(tagName,"Type"))) SetCtrlVal(fp, FP_STRING_TYPE, tagStrVal);
if(!(strcmp(tagName,"ProductID"))) SetCtrlVal(fp, FP_STRING_PRID, tagStrVal);
if(!(strcmp(tagName,"DateCreated"))) SetCtrlVal(fp, FP_STRING_CREATED, tagStrVal);
if(!(strcmp(tagName,"Version"))) SetCtrlVal(fp, FP_STRING_VERSION, tagStrVal);
}
for(i=0; i {
Ini_NthSectionName(tpFile, (i+2), &sectionNamePtr); // address of the pointer!
gTestSteps[i]->Test_ID = sectionNamePtr;
NrOfItems = Ini_NumberOfItems(tpFile, sectionNamePtr);

for(j=0; j Ini_NthItemName(tpFile, sectionNamePtr, j+1, &tagName);
Ini_GetPointerToString(tpFile, sectionNamePtr, tagName, &tagStrVal);
gTestSteps[i]->Result = 0;
if(!(strcmp(tagName,"Name"))){
gTestSteps[i]->Name = (char *)malloc(strlen(tagStrVal)+1); // allocation for Name string
strcpy(gTestSteps[i]->Name, tagStrVal);
continue;
}
if(!(strcmp(tagName, "USL"))){
gTestSteps[i]->USL = (char *)malloc(strlen(tagStrVal)+1); // allocation for USL string
strcpy(gTestSteps[i]->USL, tagStrVal);
continue;
}
if(!(strcmp(tagName, "LSL"))){
gTestSteps[i]->LSL = (char *)malloc(strlen(tagStrVal)+1); // allocation for USL string
strcpy(gTestSteps[i]->LSL, tagStrVal);
continue;
}
if(!(strcmp(tagName, "Unit"))){
gTestSteps[i]->Unit = (char *)malloc(strlen(tagStrVal)+1);
strcpy(gTestSteps[i]->Unit, tagStrVal);
continue;
}
if(!(strcmp(tagName, "Format"))){
gTestSteps[i]->Format = (char *)malloc(strlen(tagStrVal)+1);
strcpy(gTestSteps[i]->Format, tagStrVal);
continue;
}
}
}

if(tpFile) Ini_Dispose (tpFile); // Close ini file, all elements are in the memory
free(sectionNamePtr);
free(TableArray);
free(tagName);
free(tagStrVal);
return 1;
}
/
0 Kudos
Message 13 of 16
(1,849 Views)

Well, I see no evident reason for the error: where exactly are you finding it? Does it arises always in the same line or its position is varying?

It is necessary that your TestType stores pointers to strings? Could you try to modify it in order to have fixed lenght strings instead? This will reduce dynamic memory allocation and possibly eliminate this error.

 

As a side note, you can use GetGeneralErrorString ( ) to decode both User Interface Library and Toolbox errors.

Message Edited by Roberto Bozzolo on 01-20-2009 05:30 PM


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 14 of 16
(1,835 Views)

Hey Roberto,

 

I don´t understand why, but I solved the problem. I just changed the sectionNamePtr to string constants, and it works. I can´t figure out, what I do wrong with this pointer to get dynamic memory corrupted:

 NrOfItems = Ini_NumberOfItems(tpFile, "HEADER");  // Get HEADER Items
 for(i=0; i<NrOfItems; i++){
  Ini_NthItemName(tpFile, "HEADER", i+1, &tagName);
  Ini_GetPointerToString(tpFile, "HEADER", tagName, &tagStrVal);
  if(!(strcmp(tagName,"Type"))) SetCtrlVal(fp, FP_STRING_TYPE, tagStrVal);
  ...etc...

  }

 

Yes, I want to use TestType as it is. Is it problematic to allocate memory dynamically for the srtings in the struct? Should I avoid it by declaring fixed-length strings?

 

Other question: If I have a filled table control, and I want to refill it with new data, do I have to use FreeTableValStrings() - of course combined with GetTableCellRangeVals()?

 

Thanks for the sidenote, I have already invoked it!

 

regards

MB

 

 

 

0 Kudos
Message 15 of 16
(1,815 Views)

I suppose (but I'm not absolutely sure of it) this depends on sectionNamePtr being assigned a pointer to a local memory area in the line sectionNamePtr = "HEADER" and then passed to Ini_NumberOfItems which then manipulates the stringfor searchings and comparisons.

 

Regarding the table control, you can limit to pass new values to it andthey will replace previous content. FreeTableValStrings is intended to free the memori that GetTableCellRangeVals allocates if reading non-numeric values from the table.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 16 of 16
(1,810 Views)