Thread: Best method to alloc memory for string and desalloc.

  1. #31
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    but the most part is string with a variable size,

    and with resize (strcat, strcpy, substring....)

    my ICP-i7188E3 seems behave better with allocation, in some this cases.

  2. #32
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by sergioms View Post
    but the most part is string with a variable size,

    and with resize (strcat, strcpy, substring....)

    my ICP-i7188E3 seems behave better with allocation, in some this cases.
    Of course the string can be different length - as long as you know how large IT CAN BE, you will be fine with a locally allocated string.

    What do you mean "behave better"? malloc is definitely a few dozen instructions in the average/good case, and thousands of instructions in the "poor" case. stack memory allocation is at most one extra instruction - most of the time none, as it is just part of the overall local variable allocation that you have whenever there is any local variable, so essentially free. And there is no need to worry about loosing track of the memory allocated, because when you return from the function where the variable is declared, it goes away all by "magic".

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #33
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    ok, I undestand.

    in theory I accept this, but my small memory continues full.

    whatever, now the program execute by 15 minutes, before your tips, only 3.

    at someone point, the code is incorrect, and make this overflow.

    But im in a bad place, without a debug, and with poot know about C strings, pointers and memory [:S]

    I will try use coreleft to verify my remain memory....

  4. #34
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Right, so using local variables will allow you to NOT run out of memory, since you are not allocating more and more memory, you are reusing the same bit of memory. The drawback is that you would need to pass the string around from the very base-function that is the "lowest in the call-stack", otherwise you loose the strings you have picked out of the bigger package.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #35
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    is any difference of memory RAM to SRAM (in code)

    Now i change the program to always alloc variable (include local)
    and the program be executing for 1 hour.

    *alloc / free

    its crazy :S
    Last edited by sergioms; 01-06-2009 at 09:32 AM.

  6. #36
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by sergioms View Post
    is any difference of memory RAM to SRAM (in code)

    Now i change the program to always alloc variable (include local)
    and the program be executing for 1 hour.

    *alloc / free

    its crazy :S
    SRAM is a class of RAM, the other type is DRAM. The difference is that SRAM is "static", which means that as long as the power is applied, it retains it's content. DRAM is dynamic, and it needs refreshing every now and again (per RAM it retains it's contents for a few milliseconds - normally a row is refreshed every 16 microseconds or so). SRAM is also much easier to interface to the processor, as it has a more direct interface (DRAM being made as cheap as possible has a more compressed set of pins, and address to the content has to be addressed in two steps, once for the row, and once for the column within that row).

    And I'd guess you "fixed" something else while at it - or you were using memory from a function that had returned, which is a not so unusual programming error by beginners.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  7. #37
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Quote Originally Posted by matsp View Post
    SRAM is a class of RAM, the other type is DRAM. The difference is that SRAM is "static", which means that as long as the power is applied, it retains it's content. DRAM is dynamic, and it needs refreshing every now and again (per RAM it retains it's contents for a few milliseconds - normally a row is refreshed every 16 microseconds or so). SRAM is also much easier to interface to the processor, as it has a more direct interface (DRAM being made as cheap as possible has a more compressed set of pins, and address to the content has to be addressed in two steps, once for the row, and once for the column within that row).

    And I'd guess you "fixed" something else while at it - or you were using memory from a function that had returned, which is a not so unusual programming error by beginners.

    --
    Mats

    Last code Version:

    http://rafb.net/p/8f1Uh382.html

  8. #38
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    the problem has come back again.

    somebody alive?
    Last edited by sergioms; 01-06-2009 at 12:42 PM.

  9. #39
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Code:
    void EscreveDisplay (unsigned char *pMensagem){
    	unsigned char cDispPacote [51];
    	unsigned int iLims;
    	unsigned int iLenMsg, iLenCont, iContIndex;
    	int iBcc;
    
    	iLims  = 46;
    	
    	cDispPacote [0] = 129;
    	cDispPacote [1] = 126;
    	cDispPacote [2] = iLims % 256;
    	cDispPacote [3] = iLims / 256;
    	cDispPacote [4] = 1 % 256;
    	cDispPacote [5] = 1 / 256;
    	cDispPacote [6] = 0 % 256;
    	cDispPacote [7] = 0 / 256;
    	cDispPacote [8] = 76;
    	cDispPacote [9] = 202;
    		
    	iLenMsg = strlen (pMensagem);
    
    	if (iLenMsg > 40)
    		iLenMsg = 40;
    
    	if (iLenMsg < 40){
    		for(iLenCont=iLenMsg; iLenCont<40; iLenCont++)
    			strcat (pMensagem, ".");
    	}
    	
    	for(iLenCont=0; iLenCont<40; iLenCont++){
    		iContIndex = iLenCont + 10;
    		cDispPacote [iContIndex] = pMensagem [iLenCont];
    	}
    	
    	iBcc = cDispPacote [4];
    	cDispPacote [50] = iBcc;
    	cDispPacote [51] = '\0';
    	
    	for(iContIndex=0; iContIndex<=51; iContIndex++){
    		ToCom (iComDisplay, cDispPacote[iContIndex]);
    	}
    }
    pMensagem is a local variable.

    but,

    Code:
    for(iLenCont=iLenMsg; iLenCont<40; iLenCont++)
    			strcat (pMensagem, ".");
    the size is changed many times,

    this is a wrong code, or unsafe?

  10. #40
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Overall

    a few comments on the code:
    Code:
    	// Transforma os Int em Char (ASCII)
    	cSTX = STX;
    	cCR  = CR;
    	cLF  = LF;
    	cTab = TAB;
    What's the point of this - the C language will automatically convert from integer constant to char when needed. If you NEED to indicate a number constant is a char and not a integer, you can use '\nnn' where nnn is an octal number. But the use of these things, I can't actually see anywhere that you can't just use STX, CR, LF or TAB.

    You are using an awful lot of global variables - that is really not a good idea.

    Code:
    	//if (cPacote == NULL)
    	//	EscreveDisplay ("ALLOC");
    You probably DO want to check that allocations works.

    Code:
    	sprintf (cStr, "OIRS\t%s\t%s\t%d", MATERIAL_DETAIL_ID, CD_MATERIA_PRIMA, lPesoTotal);
    
    ...
    		sprintf (PesoDisplay,  "%s %d", DS_ABREVIADA, lPesoDecrescente);
    gcc complains that lPesoTotal is a long, and you are using %d. Similar problem in the second sprintf.

    Code:
    		if (lPesoDecrescente == NULL)
    			lPesoDecrescente = 0;
    "NULL" is the same as zero (aside from weird details on the subject), so aside from the warning that this compares a pointer to integer, what are you actually trying to achieve here?


    Many unused variables:
    Code:
    icp.c: In function `RecebeSerial':
    icp.c:212: warning: unused variable `iMaxLocal'
    icp.c: In function `DevolvePesagem':
    icp.c:307: warning: int format, long int arg (arg 5)
    icp.c: In function `PesaItem':
    icp.c:461: warning: int format, long int arg (arg 4)
    icp.c:474: warning: implicit declaration of function `Delay'
    icp.c: In function `OrdemProducao':
    icp.c:492: warning: unused variable `iTab'
    icp.c: In function `OrdemProducaoItem':
    icp.c:540: warning: unused variable `iTab'
    icp.c: In function `EscreveDisplay':
    icp.c:743: warning: implicit declaration of function `ToCom'
    icp.c: In function `ProcessaBuffer':
    icp.c:752: warning: unused variable `iCont'
    (Line numbers may not match your exact code, as I had to hack around missing header files in the source).

    Code:
        AddUserTimerFunction(UserCount, 200); // Adiciona  Timer para Chamar Função UserCount a cada 100 ms
    Is 200 representing 200 ms - if so, the comment is wrong, I think.

    Code:
    		if (strlen (InBuf) >= iMaxBuffer - 1){	// Limpa Buffer se Estiver Cheio
    Make iMaxBuffer an unsigned (or size_t) so that you are not comparing signed with unsigned.

    Code:
    	unsigned char *cFuncao;
    	unsigned char *cSubFuncao;
    ...
    			substring(&cPacote[0], cFuncao, 2);
    You have not allocated any memory for cFuncao, so it will probably overwrite some random memory location. Same applies for the cSubFuncao substring calls.

    Code:
    void PesaItem (void){
     
    	unsigned char *PesoDisplay = malloc (15);
    ...
    There is no reason to use malloc here.
    Code:
    void PesaItem (void){
     
    	unsigned char PesoDisplay[15];
    General coding style comments:
    You are sometimes adding a space between the function name and the (, at other times you are not. Likewise, variable names are inconsistently starting with i, c, p, etc, and at other times not. And your indentation consists of a mixture of tabs and spaces. Use either one or the other.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #41
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    thank u so much again,

    I was changed the code,

    what % I Would to use in sprintf to representate long ?

    When I Changed this:

    Code:
    unsigned char cFuncao = malloc (2);
    unsigned char cSubFuncao = malloc (2);
    But now, the program stop execution when has receive "OKOI" (OK cFuncao, OI cSubFuncao):

    Code:
    if(strlen (cPacote) > 0){
    						
    			substring(&cPacote[0], cFuncao, 2);
    			
    			if (strcmp (cFuncao, "OP") == 0){					
    				substring(&cPacote[3], cSubFuncao, iPosTam - 2);
    				OrdemProducao (cSubFuncao);
    			}
    			else if (strcmp (cFuncao, "OI") == 0){					
    				substring(&cPacote[2], cSubFuncao, iPosTam - 2);
    				OrdemProducaoItem (cSubFuncao);
    			}
    			else if (strcmp (cFuncao, "OK") == 0){	
    				substring(&cPacote[2], cSubFuncao, 2);
    				if (strcmp (cSubFuncao, "OP") == 0)	{
    					EnviaPedidoPC ("OISL", 4);		
    				}
    				else if (strcmp (cSubFuncao, "OI") == 0){	
    					lPesoTara = lPeso;
    					iPesaItem = 1;

  12. #42
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by sergioms View Post
    thank u so much again,

    I was changed the code,

    what % I Would to use in sprintf to representate long ?
    %ld

    When I Changed this:

    Code:
    unsigned char cFuncao = malloc (2);
    unsigned char cSubFuncao = malloc (2);
    Don't you get any warnings?
    malloc returns pointer, it cannot be stored in one char var

    But now, the program stop execution when has receive "OKOI" (OK cFuncao, OI cSubFuncao):
    Don't you need to store the null terminator as well?
    For example strcmp function will work only on the nul-terminated strings
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  13. #43
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And I personally would go with
    Code:
    unsigned char cFuncao[3];
    unsigned char cSubFuncao[3];
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #44
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    I has changed, with your tips.

    http://rafb.net/p/QMeEO360.html

    after some (long) time send correct, function EnviaPedidoPC send "................."
    But I Don't know the motive.

    Maybe, some point of memory has conflicted with function EscreveDisplay, in a part fill with . the string to complete 40 chars.
    Last edited by sergioms; 01-07-2009 at 08:24 PM.

  15. #45
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    the program start a process then call. IniciaMemoria to alloc this variables.

    Code:
    void IniciaMemoria (void){
    	CD_FABRICA = malloc (5);
    	BATCH_ID = malloc (11);
    	CD_PESAGEM = malloc (9);
    	CD_BALANCA = malloc (5);
    	ITEM_DESC1 = malloc (12);
    	MATERIAL_DETAIL_ID = malloc (11);
    	NR_SEQ_PESAGEM = malloc (3);
    	CD_MATERIA_PRIMA = malloc (11);
    	DS_ABREVIADA = malloc (11);
    	QT_REQUERIDA = malloc (6);
    	PR_TOLERANCIA_MIN = malloc (6);
    	PR_TOLERANCIA_MAX = malloc (6);
    	ID_PESAR = malloc (2);
    }
    then i fill this variables in 2 functions, one is these:

    Code:
    void OrdemProducao (unsigned char *pOP){	//OP	CD_FABRICA	BATCH_ID	CD_PESAGEM	CD_BALANCA	ITEM_DESC1
    	
    	unsigned char *cValor = NULL;
    	int iCont=1;
    	
    	cValor = strtok(pOP, "\t"); 	// Procura Pelo TAB
    	
    	while (cValor){
    			switch (iCont){
    				case 1:
    					strcpy (CD_FABRICA, cValor);
    					break;
    				case 2:
    					strcpy (BATCH_ID,cValor);
    					break;
    				case 3:
    					strcpy (CD_PESAGEM,cValor);
    					break;
    				case 4:
    					 strcpy (CD_BALANCA,cValor);
    					 break;
    				case 5:
    					strcpy (ITEM_DESC1,cValor);
    					EscreveDisplay (cValor, 0);
    					//EscreveDisplay ("                                        ");
    					break;
    				default:
    					break;
    			}
    			cValor = strtok(NULL, "\t");
    			iCont++;
    	}
    	
    	iStepInput0 = 2;
    	EnviaPedidoPC ("OKOP", 4);
    }
    when I Have a flow complete (process complete) then I Call this function (OrdemProducao) Again.

    I need de-allocate this variables, and re-allocate to fill it again (with other values)?

    for example:

    Code:
    void LimpaMemoria (void){
    	free(CD_FABRICA);
    	free(BATCH_ID);
    	free(CD_PESAGEM);
    	free(CD_BALANCA);
    	free(ITEM_DESC1);
    	free(MATERIAL_DETAIL_ID);
    	free(NR_SEQ_PESAGEM);
    	free(CD_MATERIA_PRIMA);
    	free(DS_ABREVIADA);
    	free(QT_REQUERIDA);
    	free(PR_TOLERANCIA_MIN);
    	free(PR_TOLERANCIA_MAX);
    	free(ID_PESAR);
    }
    Last edited by sergioms; 01-08-2009 at 07:15 AM.

Popular pages Recent additions subscribe to a feed