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

  1. #16
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    thank's a lot MK27,

    it was very good for me!

  2. #17
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    char *
         strncpy(char *restrict s1, const char *restrict s2, size_t n);
    The strncpy() function copies at most n characters from s2 into s1. If
    s2 is less than n characters long, the remainder of s1 is filled with
    `\0' characters. Otherwise, s1 is not terminated.
    From:
    http://www.manpagez.com/man/3/strncpy/
    (My bold)

    --
    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. #18
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    If s2 is less than n characters long, the remainder of s1 is filled with
    `\0' characters. Otherwise, s1 is not terminated.
    Oops! My mistake. Sorry. Thanks matsp. I'll edit my last post...
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  4. #19
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Quote Originally Posted by MK27 View Post
    Oops! My mistake. Sorry. Thanks matsp. I'll edit my last post...
    in this case,

    Code:
    int sLen;
    
    sLen = strlen(strText);
    strText [sLen ] = '\0';
    yes?

  5. #20
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by sergioms View Post
    in this case,
    [...]
    yes?
    No. strlen looks for the \0, so there is never a point in doing that. If strncpy did not add a null terminator, then strlen will give an incorrect result.

    Of course, you could always just provide an extra character so that strncpy will add a \0.
    Code:
    substring(&string[11],sub,7);		
    substring(&string[5],sub2,6);
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  6. #21
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    void substring (char *string, char *substr, int numchars) {
    	strncpy(substr,string,numchars);
            substr[numchars+1]='\0';
    }
    This is MK27's corrected code - I'm not sure if you should have the +1 there or not - I think not. But either way, something like that is correct.

    --
    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. #22
    Registered User
    Join Date
    Dec 2008
    Posts
    104
    Quote Originally Posted by matsp View Post
    Code:
    void substring (char *string, char *substr, int numchars) {
    	strncpy(substr,string,numchars);
            substr[numchars+1]='\0';
    }
    This is MK27's corrected code - I'm not sure if you should have the +1 there or not - I think not. But either way, something like that is correct.

    --
    Mats
    you should have the '+1' because otherwise it would be replacing the last character of the string with a 'string-termination'.

    and you could simply do what MK said, which is to pass the parameters of strncopy with an extra character in the 'character-length' parameter which would end up like this:
    Code:
    void substring (char *string, char *substr, int numchars) {
    	strncpy(substr,string,numchars+1);
    }

  8. #23
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Quote Originally Posted by abraham2119 View Post
    you should have the '+1' because otherwise it would be replacing the last character of the string with a 'string-termination'.

    and you could simply do what MK said, which is to pass the parameters of strncopy with an extra character in the 'character-length' parameter which would end up like this:
    Code:
    void substring (char *string, char *substr, int numchars) {
    	strncpy(substr,string,numchars+1);
    }

    in this case, the function always copy +1 char,
    ex: substring ("TESTE", strtest, 1)

    output: TE

  9. #24
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by sergioms View Post
    in this case, the function always copy +1 char,
    Yep. Which means that other version of mine would cause the same problem. So you do have to add a null terminator in that function.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  10. #25
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Code:
                    iPosStart = strpos (pPacote, cSTX);
    	iPosStart++;
    	
    	iPosEnd = strpos (pPacote, cCR);
    	
    	iPosTam = iPosEnd - iPosStart;
    	
    
    	if((iPosStart >= 0) && (iPosEnd)){
    		substring(&pPacote[iPosStart], cPacote, iPosTam);
    
    		VcomSendSocket(iUserSocket, cPacote, strlen (cPacote));
    	
    		if(strlen (cPacote) > 0){
    						
    
    			substring(&cPacote[0], cFuncao, 2);
    
    			VcomSendSocket(iUserSocket, cFuncao, strlen (cFuncao));
    			
    			if (strcmp (cFuncao, "OP") == 0){								// Recebe Ordem de Pesagem
    								substring(&cPacote[3], cSubFuncao, iPosTam - 2);
    								VcomSendSocket(iUserSocket, cSubFuncao, strlen (cSubFuncao));
    				OrdemProducao (cSubFuncao);
    pPacote: OP F04 686693 1 BL1 MASSA MONOPOROS

    Output (VcomSendSocket):

    6/1/2009 09:39:16 - Rec: PASSO 1[NULL]
    6/1/2009 09:39:16 - Rec: CC F04 686693 1 BL1 MASSA MONOPOROS�PASSO 2CC�[NULL]

    i want to get only the middle string without null and others chars.

    :S

    like my old function:

    Code:
    char *substr(const char *pstr, int start, int numchars) 
    {
    	char *pnew = malloc(numchars+1);
    	
    	strncpy(pnew, pstr + start, numchars);
    	pnew[numchars] = '\0';
    	return pnew;
    }
    Last edited by sergioms; 01-06-2009 at 05:50 AM.

  11. #26
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    void substring (char *string, char *substr, int numchars) {
    	strncpy(substr,string,numchars);
            substr[numchars+1]='\0';
    }
    should work, but I still think that if numchars is the actual number of characters you want to copy [which I think it should be], then you should set the zero to indicate the end at [numchars], not [numchars+1], since C arrays start at zero, and [numchars] really is the (numchars+1)th element - e.g. if we have a length of 2, then [2] is the third element of the array.

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

  12. #27
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    Quote Originally Posted by matsp View Post
    Code:
    void substring (char *string, char *substr, int numchars) {
    	strncpy(substr,string,numchars);
            substr[numchars+1]='\0';
    }
    should work, but I still think that if numchars is the actual number of characters you want to copy [which I think it should be], then you should set the zero to indicate the end at [numchars], not [numchars+1], since C arrays start at zero, and [numchars] really is the (numchars+1)th element - e.g. if we have a length of 2, then [2] is the third element of the array.

    --
    Mats
    Yes, Now is correct, thanks again.

    There is someone command to clear all allocated memory ?

  13. #28
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by sergioms View Post
    There is someone command to clear all allocated memory ?
    You mean "free everything", - no there is no such thing - you couldn't meaningfully make use of such a function anyways, because it would require that no functions that you ever call to the C library or such uses malloc - which they may possibly do.

    --
    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. #29
    Registered User
    Join Date
    Nov 2008
    Location
    Santa Catarina - Brasil
    Posts
    184
    humm

    then, I need use malloc always, to all strings ?

    Code:
    void ProcessaBuffer (){
    
    	unsigned char *cPacote, *cPeso;
    	int iCont;
    	int iPosStart, iPosEnd, iPosTam; 
    
    	iPosStart = strrpos (InBuf, cSTX);
    	if(iPosStart >= 0) 
    		iPosStart++;
    	
    	iPosEnd = strrpos (InBuf, cCR);
    	
    	iPosTam = iPosEnd - iPosStart;
    		
    	if((iPosStart >= 0) && (iPosEnd) && (iPosTam == 15)){
    		
    		substring(&InBuf[iPosStart], cPacote, iPosTam);
    		substring(&cPacote[1], cStatus, 1);
    		substring(&cPacote[3], cPeso, 6);
    									
    		lPeso = strtod (cPeso, NULL);
    	}
    	
    	ClearStr (InBuf);
    }
    in this code, this function is called at 200 ms, always.

    unsigned char is better then char ?

  15. #30
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    unsigned or signed char should only make a difference if you are:
    1. comparing (unsigned has no negative values, so all characters are in a uniform range 0..255, whilst characters that are above 127 become negative values in signed form).
    2. When converting to (signed) integer - an unsigned will retain the same 0..255 value, whilst the signed char will give a value -128..127.

    You certainly do not need to allocate space for all strings - you only need to allocate space if you:
    1. Use A LOT of space (several kilobytes or more)
    2. Do not know how much space you need, and the largest amount is VERY large compared to the smallest amount [particularly if you have many strings and want to conserve space].

    Using
    Code:
    char str[SIZE];
    will create a string of SIZE elements, which should work for cases where SIZE can be determined before you run the program - and as long as the largest size you need is less than (say) a few hundred bytes, it's the best way to get space for a string.

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

Popular pages Recent additions subscribe to a feed