all code correct glibc Double free/ corruption

Ok, I am having a weird problem I will call the below function over 1000 times I checked by debugging. Then it will through a glibc double free | corruption error all of a sudden. It processes all the way to the first free statement and when it hits that it gives the error. I used debugging to figure that out too. I have tested for a null return from malloc and it was good, I used the statement and then when I come to free it I get an error!
1: what are the possible causes of this?
2: how can I deal with it?
3: should I use try catch for the free statement and if I do will I get a memory leak.

Here is a sample of the code that is being called:

void SqlDataBase::InsertString(unsigned long int ID ,char *VarString,size_t VarStringSize)
{
unsigned int long NewStringLength;
char* NewUrlHtml = (char*)malloc(VarStringSize*2+1);
if (NewUrlHtml != NULL)
{
NewStringLength = mysql_real_escape_string(conn, NewString, VarString, VarStringSize);
char *SqlStatement = (char*) malloc(sizeof(unsigned long int)*2+NewStringLength+70);
if (SqlStatement != NULL)
{
sprintf(SqlStatement, "INSERT INTO Table set id='%lu', String = '%s', Stringlength = '%lu'",VarID, NewString,VarStringSize);
process_select_statement(SqlStatement);
// Problem is here I checked using debugging The sqlstatment process correctly and returns
free (SqlStatement);
}
else
{
printf ("molloc failed");
}
free (NewUrlHtml);
}
else
{
printf ("molloc failed");
}
};
When I pasted the code it went and un tabbed it all sorry.
If this is the wrong sit for plain c code please provide me with a proper forum, I have not been able to find one any place. The program I am working on can only be written in c due to conflics with other libraries.
Thank you in advance.
Donald
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void SqlDataBase::InsertString(unsigned long int ID, char *VarString, size_t VarStringSize)
{
    unsigned int long NewStringLength;

    char* NewUrlHtml = (char*)malloc(VarStringSize*2+1);

    if (NewUrlHtml != NULL)
    {
        NewStringLength = mysql_real_escape_string(conn, NewString, VarString, VarStringSize);
        
        char *SqlStatement = (char*) malloc(sizeof(unsigned long int)*2+NewStringLength+70);

        if (SqlStatement != NULL)
        {
            sprintf(SqlStatement, "INSERT INTO Table set id='%lu', String = '%s', Stringlength = '%lu'",VarID, NewString,VarStringSize);
            process_select_statement(SqlStatement);
            // Problem is here I checked using debugging The sqlstatment process correctly and returns
            free (SqlStatement);
        }
        else
        {
            printf ("molloc failed");
        }
        free (NewUrlHtml);
    }
    else
    {
        printf ("molloc failed");
    }
}


Where did NewString variable suddenly appear from and what happened to NewUrlHtml

If you comment out the line free (SqlStatement); does it work??


What does the process_select_statement function do? have you got a definition for it.

suggest you put in a trace statement like:

printf ("%d %d\n", strlen(SqlStatement), sizeof(unsigned long int)*2+NewStringLength+70)
Last edited on
Sorry I modified the statment to make it smaller, was a big tired and frustrated. Here is the code as follow: Question how do I insert my code like you guys. I tried to read it up, but did not find a information on how to post code properly, sorry.

Here is the above code as I have it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void SqlDataBase::Insert_Url_Html(unsigned long int VarUrlExtID ,char *VarHtmlBody,size_t VarHTMLBodySize)
{
    SqlFunction = InFunctionInsertUrlHtml;
    unsigned int long NewUrlHtmlLength;
    char* NewUrlHtml = (char*)malloc(VarHTMLBodySize*2+1);
    if (NewUrlHtml != NULL)
    {
        NewUrlHtmlLength = mysql_real_escape_string(conn, NewUrlHtml, VarHtmlBody, VarHTMLBodySize);
        char *SqlStatement = (char*) malloc(sizeof(unsigned long int)*2+NewUrlHtmlLength+70);
        if (SqlStatement != NULL)
        {
            sprintf(SqlStatement, "INSERT INTO urlhtml set urlid='%lu', htmlbody = '%s', htmlbodylength = '%lu'",VarUrlExtID, NewUrlHtml,VarHTMLBodySize);
            process_select_statement(SqlStatement);
/* TODO (donald#1#):  deal with thedoublefreeproblem */
            free (SqlStatement);
        }
        else
        {
            printf ("molloc failed");
        }
        free (NewUrlHtml);
    }
    else
    {
        printf ("molloc failed");
    }
};



The following is the other functions being called:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
int SqlDataBase::process_select_statement(char *VarSqlStatment)
{
    MYSQL_RES *res_set;
    int       status;
    int       keep_going = 1;
  if (mysql_query (conn, VarSqlStatment) != 0)  /* the statement(s) failed */
  {
    print_error (conn, "Could not execute statement(s)");
    return 0;
  }

  /* the statement(s) succeeded; enter result-retrieval loop */
  do {
    /* determine whether current statement returned data */
    res_set = mysql_store_result (conn);
    if (res_set)      /* a result set was returned */
    {
      /* process rows and then free the result set */
      process_result_set (conn, res_set);
      mysql_free_result (res_set);
    }
    else              /* no result set was returned */
    {
      /*
       * does the lack of a result set mean that the statement didn't
       * return one, or that it should have but an error occurred?
       */
      if (mysql_field_count (conn) == 0)
      {
        /*
         * statement generated no result set (it was not a SELECT,
         * SHOW, DESCRIBE, etc.); just report rows-affected value.
         */
      }
      else  /* an error occurred */
      {
        print_error (conn, "Could not retrieve result set");
        keep_going = 0;
      }
    }
    /* determine whether more results exist */
    /* 0 = yes, -1 = no, >0 = error */
    status = mysql_next_result (conn);
    if (status != 0)    /* no more results, or an error occurred */
    {
      keep_going = 0;
      if (status > 0)   /* error */
        print_error (conn, "Could not execute statement");
    }
  } while (keep_going);
};
void SqlDataBase::process_result_set (MYSQL *conn, MYSQL_RES *res_set)
{
    MYSQL_ROW row;
    unsigned int i;
    // Let the program know that the result set was empty
    while ((row = mysql_fetch_row (res_set)) != NULL)
    {
        // Let the program know that the result set was empty
        ResultSetThere = true;
        for (i = 0; i < mysql_num_fields (res_set); i++)
        {
            if (i > 0)
            {
                fputc ('\t', stdout);
            }
	    //function here for dealing with the returned results, but took them out to make code smaller and the problem function will never make it here
            fputc ('\n', stdout);
        }
        if (mysql_errno (conn) !=0)
        {
            print_error (conn, "mysql_fetch_row() failed");
        }
        else
        {
//            printf ("Number of rows returned: %lu\n",
//                         (unsigned long) mysql_num_rows (res_set));
        }
    }
}
/* #@ _PRINT_ERROR_ */
void SqlDataBase::print_error (MYSQL *conn, char *message)
{
  if (conn != NULL)
  {
    fprintf (stderr, "Error %u (%s): %s\n",
             mysql_errno (conn), mysql_sqlstate (conn), mysql_error (conn));
  }
}

I will try using the trace statement you suggested the next time I fire this thing up. It is a rare problem, so I will put the trace statement in and dump it do my debug function, it will record this information ever time this function is called and when it kicks. I will have all this results logged. Why would I be intrested in this information, it can not be zero as I have the written sql statement or are you thinking that there may be no value or length in one of my varablies?
Thank you for the resonse.
Donald
oh I figured out the code thing.
Thanks,
Donald
I am going to try and take out the free statement if I still am having problems, but that would cause a memory leak no?
It is going to take time to get results for this as it is one of those happens when it feels like things.
the error does say corruption or double free.
Maybe the SqlStatement buffer is undersized.
It looks like a bit of a dodgy calculation - I would say make it bigger, there will be no harm done,
maybe start by making it obviously too big and see what happens:

char *SqlStatement = (char*) malloc(sizeof(unsigned long int)*2+NewUrlHtmlLength+200);
Last edited on
char *SqlStatement = (char*) malloc(sizeof(unsigned long int)*2+NewUrlHtmlLength+70);
I bet I need a brackets around this (2+NewUrlHtmlLength+70) so it adds the total of the lenght * sizeof.
That makes sense.
Only thing is though you would think it would kick alot faster then that the way it is now.
I am going to change that add the 200 with a bug detection and see what happens, the next time I fire it up.

Thanks,
Donald
That seemed to do the trick after calling the function 14127 times had no error's. Problem solved. Onto the next research project charater sets. Intresting all this learning.
Topic archived. No new replies allowed.