Thread: using malloc method to hold the converted data to string/char array

  1. #1
    Registered User
    Join Date
    Jul 2004
    Posts
    222

    using malloc method to hold the converted data to string/char array

    I would like to convert my code that uses an array that's constantly allocated to hold the converted data from an analog to digital converter into a method where the result of the sprintf conversion would be stored in a pointer as long as I need it. Below shows two versions of my code and the red highlighted line shows the task that I'm having trouble with. I apologize for the lackluster tab formatting of the code in advance. Thanks.

    explicitly allocated char array version:
    Code:
    // Data Logging Scale                 <[email protected]>
    // Created: Nov 3, 2007
    // Revised: Nov 15, 2007
    
    #include <built_in.h>
    #include "typedefs.h"
    #include "usart.h"
    #include "LCD4.h"
    
    #define BUFFER_SIZE 5
    
    void delay(uint number)
    {
          while(--number > 0);
    }
    
    void main() {
      uint temp_res, last_temp_res;
      int n;
      char adc[BUFFER_SIZE];            // temporary adc string value
    
      OSCCON = 0x70;        /* internal oscillator at 8 Mhz, system clock = internal oscillator*/
      OSCTUNE = 0x00;        /* oscillator tuning register at max frequency */
     	CMCON = 7;              // turn off comparators
     	Delay_ms(20);            // system wide delay of 20 ms
     	
      ADCON1 = 0x0e;          // Configure Vref and AN0
      TRISA  = 0x01;          // PORTA is output except RA0 (AN0)
      TRISB  = 0x00;          // all PORTB pins are output
      TRISC  = 0x00;          // PORTC is outputs
      
      LCD4_INIT();            // initialize the LCD
      LCD4_OUT("Weight (kg) : ");       // output some text
      
    
      while(1)
      {
        temp_res = Adc_Read(0);
        n = sprintf(adc, "%u", temp_res);
        if (n < 0 || n >= BUFFER_SIZE)
          break;
        if (abs(temp_res - last_temp_res) < 10)
        {
              LCD4_CMD(142);                   // move cursor position to character #15
              LCD4_OUT(adc);              // output the a/d result
        }
        last_temp_res = temp_res;
      }
    }
    malloc for a char pointer version:
    Code:
    // Data Logging Scale                 <[email protected]>
    // Created: Nov 3, 2007
    // Revised: Dec 15, 2007
    
    #include <built_in.h>
    #include "typedefs.h"
    #include "usart.h"
    #include "LCD4.h"
    
    #define BUFFER_SIZE 5
    
    void delay(uint number)
    {
          while(--number > 0);
    }
    
    void main() {
      uint temp_res, last_temp_res;
      char *temp_res_text;               // dynamic character array pointer
      int n;
    
      OSCCON = 0x70;        /* internal oscillator at 8 Mhz, system clock = internal oscillator*/
     	OSCTUNE = 0x00;        /* oscillator tuning register at max frequency */
     	CMCON = 7;              // turn off comparators
     	Delay_ms(20);            // system wide delay of 20 ms
     	
      ADCON1 = 0x0e;          // Configure Vref and AN0
      TRISA  = 0x01;          // PORTA is output except RA0 (AN0)
      TRISB  = 0x00;          // all PORTB pins are output
      TRISC  = 0x00;          // PORTC is outputs
      
      LCD4_INIT();            // initialize the LCD
      LCD4_OUT("Weight (kg) : ");       // output some text
    
      while(1)
      {
         temp_res = Adc_Read(0);          // sample a/d converter
         
         temp_res_text = (char *) malloc(5);        // allocate 5 character bytes
         
         // How would i use sprintf function to convert temp_res data into string format
         // in resultant pointer temp_res_text?
         
         LCD4_CMD(142);                   // move cursor position to character #15
         LCD4_OUT(temp_res);              // output the a/d result
         
         free(temp_res_text);             // free allocated character bytes
      }
    }
    Please let me know if there are any functions that you don't understand as those functions have been tested to work up to the specification so far, hence why I didn't include them b/c they are not the source of the problem.

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    An array and a pointer can usually be treated the same because is your previous example, adc is automatically cast to char* (or char[]), so it's not different from what you used to do before.
    So just do as you did before with sprintf.
    But I urge to you to beware - 5 chars is not enough to hold an uint. An uint can hold numbers up to 10 digits. So that means you should at least allocate 10 + 1 bytes of memory to hold the number.
    void main() is also undefined; it should be int main(). Read my signature for more information.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    You forgot to #include <stdio.h> and <stdlib.h>

    // How would i use sprintf function to convert temp_res data into string format
    // in resultant pointer temp_res_text?
    You already have the answer in your first version:
    Code:
    n = sprintf(temp_res_text, "%u", temp_res);
    BTW, don't cast the return type of malloc(). See the FAQ for why it's bad.

  4. #4
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    Elysia: What do you mean 5 chars is not enough to hold an uint? My uint would have at max 10 bits resolution.
    cpjust: Thanks for your time on the casting issues. I copied the example code from cplusplus.com's explanation of malloc(). Also, stdio.h and stdlib.h are ignored on purpose in mikroC development suite, I think. Hence why I didn't include them.

  5. #5
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by stanlvw View Post
    Elysia: What do you mean 5 chars is not enough to hold an uint? My uint would have at max 10 bits resolution.
    In that case, an unsigned short is all you need; but even then the largest number (on most systems) is 65535, so you'd still need an extra byte to store the '\0' in the string.

  6. #6
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Code:
         temp_res_text = (char *) malloc(5);        // allocate 5 character bytes
         
         // How would i use sprintf function to convert temp_res data into string format
         // in resultant pointer temp_res_text?
    I should be asking to look into one of your header files and see who much the uint (It might have been defined somewhere there) takes in terms of memory. Make sure u allocate the right amount of space. Which MicroControl are you programming? The only problem with sprintf function is that, its up to the programmer to make sure that Dest string have enough memory to fit in your source informatoin. Perhaps you can use snprintf function to avoid more complications, something as follow

    Code:
    #define MAXSIZ  10
    
    char *Dest, *Extra;
    int Len;
    
    Dest = malloc(sizeof(char) * MAXSIZ);
    
    if(Dest = NULL)
    {
       printf("Error: No enough memory\n");
       return 1;
    }
    
    if( ( Len = snprintf(Dest, MAXSIZ, "&#37;u", temp_res) ) >= MAXSIZ )
    {
        Extra = malloc( sizeof(char) * Len + 1 );
        
        if(Extra == NULL)
        {
           printf("Error: No enough memory\n");
           return 1;
        }
        free(Dest);
        snprintf( Dest = Extra, Len, "%u", temp_res );
    }
    ssharish

  7. #7
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    The biggest number that I'm going to get is 1024.

  8. #8
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    ssharish2005: uint is a typedef type that's an unsigned int, which I think it's 10-bit resolution. I'm programming on a PIC18F2620 microcontroller using mikroC.

  9. #9
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Quote Originally Posted by stanlvw View Post
    ssharish2005: uint is a typedef type that's an unsigned int, which I think it's 10-bit resolution. I'm programming on a PIC18F2620 microcontroller using mikroC.
    Thats fine, do this

    Code:
    Dest = malloc(sizeof(char) * sizeof(uint) + 1 );
    ssharish

  10. #10
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    Do I need to change anything else on Extra pointer?

  11. #11
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Quote Originally Posted by stanlvw View Post
    Do I need to change anything else on Extra pointer?
    Perhaps YES, you will have to free Extra before you leave the If statment i suppose, otherwise it becomes a memory leak. Sorry

    Code:
    #define MAXSIZ  sizeof(uint) 
    
    char *Dest, *Extra;
    int Len;
    
    Dest = malloc(sizeof(char) * MAXSIZE + 1 );
    
    if(Dest = NULL)
    {
       printf("Error: No enough memory\n");
       return 1;
    }
    
    if( ( Len = snprintf(Dest, MAXSIZ, "&#37;u", temp_res) ) >= MAXSIZ )
    {
        Extra = malloc( sizeof(char) * Len + 1 );
        
        if(Extra == NULL)
        {
           printf("Error: No enough memory\n");
           return 1;
        }
        free(Dest);
        snprintf( Dest = Extra, Len, "%u", temp_res );
        free(Extra);
    }
    ssharish

  12. #12
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    It appears that malloc isn't supported in mikroC built-in. I guess it's a hardware related problem with respect to memory allocation. I guess I would have to try my luck on their forums.

  13. #13
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    i should have asked what compiler are using before?. And perharps you could cross compile the library to support the target board. I program Intel PXA255 series, my vendore gave me all cross compiled library along with board. Perhaps contact vendor and see if u get one. Or you can compile it by your self.

    ssharish

  14. #14
    Registered User
    Join Date
    Jul 2004
    Posts
    222
    I am using mikroC compiler on Microchip PIC18F series microcontroller. I have contacted the vendor mikroelektronika about it already. In the meanwhile, I'm trying to implement the source code of those missing functions.

  15. #15
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    I'm trying to implement the source code of those missing functions.
    Do u mean malloc and free?

    ssharish

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Line of data input method
    By larry_2k4 in forum C Programming
    Replies: 2
    Last Post: 04-28-2009, 11:34 PM
  2. Fixing my program
    By Mcwaffle in forum C Programming
    Replies: 5
    Last Post: 11-05-2008, 03:55 AM
  3. how do you input data from a file into an array?
    By jorgejags in forum C Programming
    Replies: 5
    Last Post: 11-03-2008, 02:48 PM
  4. xor linked list
    By adramalech in forum C Programming
    Replies: 23
    Last Post: 10-14-2008, 10:13 AM
  5. Replies: 2
    Last Post: 07-11-2008, 07:39 AM