Thread: malloc problem

  1. #1
    Just kidding.... fnoyan's Avatar
    Join Date
    Jun 2003
    Location
    Still in the egg
    Posts
    275

    malloc problem

    hi
    I have the code below
    Code:
    void get_value(char *url_str,int count)
    {
     char *var[64],*tmp[64],*str;
     int len,i=0,j,l;
     
     len=strlen(url_str);
     str=(char *)malloc(len*sizeof(char));
     strncpy(str,url_str,len);
     
      l=strlen(str); 
      printf("CALLOC STRING : %s \nBellek Uzunlugu : %d\n",str,l);
      printf("URL    STRING : %s \nBellek Uzunlugu : %d\n",url_str,len); 
     
     for( j=count;j>0;j--)
     {
      if (!i)
       tmp[i]=strtok(str,"&");
      else
       tmp[i]=strtok((char *)NULL,"&");
       i++;
     }
     
     for (j=0;j<count;j++)
     {
      var[j]=strtok(tmp[j],"=");
      var[j]=strtok((char *)NULL,"=");
     }
    
     free(str);
      printf("tmp :\n1)%s\n2)%s\n3)%s\n4)%s\n",tmp[0],tmp[1],tmp[2],tmp[3]);
      printf("\nvar :\n1)%s\n2)%s\n3)%s\n4)%s\n",var[0],var[1],var[2],var[3]);
    }
    the code above prints the variable and their values coming from an URL encoded string. (like host=localhost&user=default...)
    count is the number of "var=value" pairs.
    When I run the code, always first var name is not printed! But if I add at least 30 to len it works fine :/ confused?!?
    I get the lenght of string and then allocate a buffer for it but it does not print all the data. Why?

  2. #2
    Registered User
    Join Date
    Aug 2003
    Posts
    51
    First thing is it should be

    Code:
    str=(char *)malloc(len*sizeof(char) + 1);
    To account for the string termintor since strlen only returns the length of the string, which is the number of characters in a string minus the string terminator.

    also

    Code:
    strncpy(str,url_str,len+1);
    although personally i'd just use strcpy since you what to entire string to copy anyway.

    I think your problem is that your freeing memory then trying to read from it.

    the pointers in tmp and var point to characters in str, but your freeing str, then reading from it using tmp and var.

    Hopefully that solves the problem
    Last edited by Kyro; 09-19-2003 at 09:12 AM.

  3. #3
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Would something like this -- a different approach -- do what you want?
    Code:
    #include <stdio.h>
    #include <string.h>
    
    struct sPair
    {
       char *name;
       char *value;
    };
    
    void parse(char *url, struct sPair *pair, size_t size)
    {
       char *ptr = url;
       for( ; size--; ++pair)
       {
          pair->name = strtok(ptr, "=");
          if(pair->name == NULL)
          {
             break;
          }
          else
          {
             if(ptr != NULL)
             {
                ptr = NULL;
             }
          }
          pair->value = strtok(ptr, "&");
          if(pair->value == NULL)
          {
             break;
          }
       }
    }
    
    int main(void)
    {
       char url[] = "host=localhost&user=default";
       struct sPair pair[5] = {0};
       size_t i;
       parse ( url, pair, sizeof pair / sizeof *pair );
       for(i = 0; i < sizeof pair / sizeof *pair; ++i)
       {
          if(pair[i].name != NULL && pair[i].value != NULL)
          {
             printf("name = %s, value = %s\n", pair[i].name, pair[i].value);
          }
       }
       return 0;
    }
    
    /* my output
    name = host, value = localhost
    name = user, value = default
    */
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  4. #4
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    If you want to avoid strtok, you can use something like this:
    Code:
    char szParams[] = "host=localhost&user=default"
    BOOL bInValue;
    char * szParamName;
    char * szParamValue;
    
    while (*szParams) {
    
    	if (*szParams == '=' && !bInValue) {
    		bInValue = TRUE;
    		szParamValue = szParams + 1;  // Param value starts after the equal
    		*szParams = '\0';            // Terminate param name at equal
    	}
    	else if (*szParams == '&' && bInValue) {
    		bInValue = FALSE;
    		*szParams = '\0';   // Terminate param value at ampersand
    		szParamName = szParams + 1;  // Start new param name after ampersand
    
    		printf("%s = %s", szParamName, szParamValue);
    	}
    
    	szParams++;  // Move to next character
    }
    
    // print last value - terminated by null, not '&'
    if (bInValue) printf("%s = %s", szParamName, szParamValue);
    Last edited by anonytmouse; 09-19-2003 at 12:01 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  2. Replies: 12
    Last Post: 06-24-2005, 04:27 PM
  3. malloc and realloc
    By odysseus.lost in forum C Programming
    Replies: 3
    Last Post: 05-27-2005, 08:44 AM
  4. freeing problem with concurrent processes
    By alavardi in forum C Programming
    Replies: 2
    Last Post: 03-07-2005, 01:09 PM
  5. half ADT (nested struct) problem...
    By CyC|OpS in forum C Programming
    Replies: 1
    Last Post: 10-26-2002, 08:37 AM