Thread: Frustrated: Dynamically Allocating String & Sending Out Of Function

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    15

    Frustrated: Dynamically Allocating String & Sending Out Of Function

    I'm about to jump off of a roof. Here's the meat & potatoes code:

    Code:
    char *make_new_query(char *hd)
    {
            int i, j, k;
            char hard_drive[4];
            char buffer[5];
            char class_part[50];
            char query[3000];
            char prefix[100] = "SELECT * FROM (SELECT * FROM main WHERE (";
    
            strcpy(hard_drive, hd);
    
            for(i=0; i<8; i++) {
                    for(j = 0; j < keytab[i].total_songs; j++) {
                            if(i == 0) { 
                                    strcpy(query, prefix);
                            } else {
                                    strcat(query, prefix);
                            }
    
                            for(k = keytab[i].low_range; k < (keytab[i].high_range + 1); k++) {
                                    snprintf(buffer, 5, "%i", k);
    
                                    strcat(query, "class_no = ");
                                    strcat(query, buffer);
    
                                    if(k != keytab[i].high_range)
                                            strcat(query, " OR ");
                            }
    
                            strcat(query, ") AND hd=\'");
                            strcat(query, hard_drive);
    
                            if(strcmp(hard_drive, "A") == 0) strcpy(hard_drive,"B");
                            else if (strcmp(hard_drive, "B") == 0) strcpy(hard_drive,"A");
    
                            strcat(query, "\' ORDER BY random() limit 1)");
    
                            if(i != 7) strcat(query, " UNION ALL "); 
                    }
            }
    
            strcat(query, ";");
    
            return query;
    }
    So, I'm making a custom query, and (as you can see) I've resorted to making this huge char buffer on the stack. The size of query is 1/10 of the size that I want (I'm still testing). I want to dynamically allocate query since it's the one that changes sizes, depending.

    Here's the other code I was using to dynamically allocate query.

    Code:
    char *safestrcat(char *to, char *from)
    {
            size_t len;
            char *buffer;
    
            len = (strlen(to) + strlen(from) + 1);
    
            buffer = xrealloc(to, len);
    
            strcat(buffer, to);
            strcat(buffer, from);
    
            return buffer; 
            
    }
    I kept getting an error with this one! Now, in "The GNU C Library" by S. Loosemore, they say "Programmers using the strcat or wcscat function...can easily be recognized as lazy and reckless." Yet, before the code above, I tried the code they had on pp. 102-103, and it didn't work, and I don't understand why it didn't (they have one misspelling in there I fixed, but that wasn't it).

    Here's my xrealloc code:

    Code:
    void *xrealloc(void *ptr, size_t size)
    {
            register void *value = realloc(ptr, size);
    
            if(value == 0)
                    HandleError(errno, "xralloc", "xrealloc failed");
    
            return value;
    }
    So, I wanted to strdup the first part of the query, and then use my safestrcat function for the rest of it. However, when I had it in the function, it would take until I put the k variable into the buffer, safestrcat'ed buffer to class_part, and then it would segmentation fault when I tried to safestrcat class_part onto query. My safestrdup function was this:

    Code:
    char *safestrdup(const char *s)
    {
            char *retval;
    
            retval = strdup(s);
    
            if (!retval) HandleError(0, "strdup", "dup %s failed", s);
    
            return retval;
    }
    I think I'm missing something about how strings work. If someone could help me out of this mess, I'd appreciate it. I don't want to leave this code like this (although it works). My goal is to dynamically allocate the query variable. Thanks, and I hope I made sense.

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Try to narrow down the code segment that is segfaulting by running it thro' a debugger.

  3. #3
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Even if you dynamically allocate the query variable you need to have some idea of how much memory you want to allocate for it. So the first question would be how much memory does it need?

    Secondly, I think it would be useful it you also posted the code where you initialize the parameters you are passing to these functions, particularly the query function.
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  4. #4
    Registered User
    Join Date
    Apr 2010
    Posts
    15

    I'm OK

    Claudiu - I understand what you're saying. I got it to work, just not the dynamic part (yet). The query that I make is huge (40,000 char's), and I was able to fit it on the stack. Thank you.

  5. #5
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Quote Originally Posted by soj0mq3 View Post
    Claudiu - I understand what you're saying. I got it to work, just not the dynamic part (yet). The query that I make is huge (40,000 char's), and I was able to fit it on the stack. Thank you.
    Wow! Really? You actually have a 40,000+ char query? Well that's certainly impressive but I am dying to ask: what does this database store for God's sake? Could the DB table relations be designed in a better way? (just asking, not being ironic in the least)
    1. Get rid of gets(). Never ever ever use it again. Replace it with fgets() and use that instead.
    2. Get rid of void main and replace it with int main(void) and return 0 at the end of the function.
    3. Get rid of conio.h and other antiquated DOS crap headers.
    4. Don't cast the return value of malloc, even if you always always always make sure that stdlib.h is included.

  6. #6
    Registered User sbaginov's Avatar
    Join Date
    May 2010
    Location
    Italy
    Posts
    19
    At the moment I got no time, so I will give you some code to look at instead: I usually allocate memory with this function:
    Code:
    char *ds_new(const unsigned int len) {
       char *r;
    
       if (C90_MAXLEN < len) {
          char m[MAX_STRLEN] = "";
          sprintf(m, "The requested chunk of %d chars is longer than "
             "the allowed %d chars (ISO C90)", len, C90_MAXLEN);
          fatal_error("ds_new", m);
       }
    
       r = (char *) calloc(len + NULL_CHAR, sizeof(char));
    
       if (NULL == r)
          fatal_error("ds_new", "Out of memory");
    
       return r;
    }
    and resize the chars array with
    Code:
    void ds_redim(char s[], const int len) {
       if (C90_MAXLEN < len) {
          char m[MAX_STRLEN] = "";
          sprintf(m, "The requested chunk of %d chars is longer than "
             "the allowed %d chars (ISO C90)", len, C90_MAXLEN);
          fatal_error("ds_redim", m);
       }
    
       s = (char *) realloc(s, len + NULL_CHAR);
    
       if (NULL == s)
          fatal_error("ds_redim", "Out of memory");
    
       s[len] = '\0';
    }
    where
    Code:
    #define C90_MAXLEN 509
    #define NULL_CHAR 1
    #define MAX_STRLEN 255
    When I have finished, I run free() on the dynamic string that these 2 functions give back.
    If you delete the fatal_error() statements, they are ready for you to go.

    HTH

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  2. String Class
    By BKurosawa in forum C++ Programming
    Replies: 117
    Last Post: 08-09-2007, 01:02 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. String issues
    By The_professor in forum C++ Programming
    Replies: 7
    Last Post: 06-12-2007, 09:11 AM
  5. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM