Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: segmentation fault--and I think I own the memory

  1. #1
    Join Date
    Mar 2009
    Location
    pennslyvania
    Beans
    122
    Distro
    Ubuntu 10.10 Maverick Meerkat

    segmentation fault--and I think I own the memory

    Code:
    static int cb_create_container(void* ptr_4th_arg, int num_col, char** col_text, char** col_name)
    {
        int num_rec;
        sscanf(col_text[0], "%d", &num_rec);
        printf("%d\n",num_rec);
        if(!*(struct Out_put**)ptr_4th_arg)
        {
            struct Out_put** pp_out = (struct Out_put**)ptr_4th_arg;
            *pp_out = (struct Out_put*) calloc(num_rec + 1,sizeof(struct Out_put));
            strcpy(pp_out[num_rec]->field_name, "test"); /*Right here I get a seg fault and I cannot see why I don’t own this piece of memory???*/
        }
        return 0;
    }
    It seems to me I am doing every thing right but I obviously am not.

  2. #2
    Join Date
    Jun 2011
    Location
    Wollongong, Australia
    Beans
    148
    Distro
    Ubuntu 11.04 Natty Narwhal

    Re: segmentation fault--and I think I own the memory

    Not an expert by any means, been a few years since I did any c/c++, but here goes:

    strycpy isn't overrunning the length of the destination is it? Pretty sure it doesn't check if has enough length in the destination. Maybe check the length of field_name in the struct before writing?

    Do you have to dereference pp_out in the strcpy line? Like I said its been ages, but when I used to get seg faults with pointers and I didn't know what was going on, I'd just start whacking in *'s (or deleting them) and then try again.

  3. #3
    Join Date
    Apr 2007
    Location
    NorCal
    Beans
    1,149
    Distro
    Ubuntu 10.04 Lucid Lynx

    Re: segmentation fault--and I think I own the memory

    You never make sure ptr_4th_arg is not null before dereferencing it. Also: how big is field_name?
    Posting code? Use the [code] or [php] tags.
    I don't care, I'm still free. You can't take the sky from me.

  4. #4
    Join Date
    Mar 2009
    Location
    pennslyvania
    Beans
    122
    Distro
    Ubuntu 10.10 Maverick Meerkat

    Re: segmentation fault--and I think I own the memory

    this is the struct:
    Code:
    struct Out_put
    {
        char field_name[25];
        char field_value[25];
    };
    edit: decided it was easier to show the whole file than just part.
    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<assert.h>
    #include<string.h>
    #include <sqlite3.h>
    #include "create_and_pop.h"
    
    static int callback(void* ptr_4th_arg, int num_col, char** col_text, char** col_name)
    {
        int i =0;
        struct Out_put** pp_out = (struct Out_put**)ptr_4th_arg;
        for(i = 0; i < num_col; i++)
        {
            strcpy(pp_out[i]->field_name, col_name[i]);
            strcpy(pp_out[i]->field_value, col_text[i]);
        }
    
        return 0;
    }
    
    static int cb_create_container(void* ptr_4th_arg, int num_col, char** col_text, char** col_name)
    {
        int num_rec;
        sscanf(col_text[0], "%d", &num_rec);
        printf("%d\n",num_rec);
        if(!*(struct Out_put**)ptr_4th_arg)
        {
            struct Out_put** pp_out = (struct Out_put**)ptr_4th_arg;
            *pp_out = (struct Out_put*) calloc(num_rec + 1,sizeof(struct Out_put));
            strcpy(pp_out[num_rec]->field_name, "test"); 
        }
        return 0;
    }
    
    void summary(const char* db_name)
    {   
        char* error_msg = 0;
        char create_summary_string[]
            = "select pay_grp, sum(gross) as \"total\" from payroll_foot group by pay_grp;"; 
        int rc = 0;
        sqlite3* db = 0;
        struct Out_put* out_structure = 0;
        sqlite3_open(db_name, &db);
        rc = sqlite3_exec(db, "select count(*) as \"data_size\" from  payroll_foot;", 
                cb_create_container, &out_structure, &error_msg);
        if( rc!=SQLITE_OK )
        {
            fprintf(stderr, "SQL error: %s\n", error_msg);
            sqlite3_free(error_msg);
        }
    
        rc = sqlite3_exec(db, create_summary_string, callback, &out_structure, &error_msg);
        if( rc!=SQLITE_OK )
        {
            fprintf(stderr, "SQL error: %s\n", error_msg);
            sqlite3_free(error_msg);
        }
    
        printf("%s\n", out_structure[0].field_name);
      
        sqlite3_close(db);
    }
    Last edited by audit; September 1st, 2011 at 02:47 AM. Reason: did not give adequate information

  5. #5
    Join Date
    Jul 2006
    Beans
    193

    Re: segmentation fault--and I think I own the memory

    As schauerlich said, you're not checking for NULL before dereference, so that's something you should do.

    Also, your function takes 4 arguments, but uses only 2 .... any reason for that?

    It's hard to figure out everything that could be wrong, but I would take a real close look at num_rec. What is the value of that variable before it's used in pp_out[num_rec]?

    If you're calling pp_out[0], that seems fine, but I'm not so sure about pp_out[1], or anything higher.

    You ran this through gdb already, right?

  6. #6
    Join Date
    Mar 2009
    Location
    pennslyvania
    Beans
    122
    Distro
    Ubuntu 10.10 Maverick Meerkat

    Re: segmentation fault--and I think I own the memory

    As schauerlich said, you're not checking for NULL before dereference, so that's something you should do.
    done but not the problem.

    Also, your function takes 4 arguments, but uses only 2 .... any reason for that?
    sqlite designed the interface so my callback must conform to it unless I want to write my own

    It's hard to figure out everything that could be wrong, but I would take a real close look at num_rec. What is the value of that variable before it's used in pp_out[num_rec]?
    the value for this test is 200--I have tested it with a printf in the function and it is being set at 200.

    If you're calling pp_out[0], that seems fine, but I'm not so sure about pp_out[1], or anything higher.
    your right pp_out[0] can be set- I have tested that but everything else is a seg fault.

    You ran this through gdb already, right?
    yes, but I am a real novice with gdb and all I can tell is that it will not let me do anything to pp_out[200].

    Thanks for reading.

  7. #7
    Join Date
    Nov 2005
    Location
    Bordeaux, France
    Beans
    11,297
    Distro
    Ubuntu 12.04 Precise Pangolin

    Re: segmentation fault--and I think I own the memory

    Quote Originally Posted by audit View Post
    yes, but I am a real novice with gdb and all I can tell is that it will not let me do anything to pp_out[200].
    Run it in valgrind. We can't test anything without a main.
    Last edited by Bachstelze; September 1st, 2011 at 12:22 PM.

  8. #8
    Join Date
    Mar 2009
    Location
    pennslyvania
    Beans
    122
    Distro
    Ubuntu 10.10 Maverick Meerkat

    Re: segmentation fault--and I think I own the memory

    If you allocate memory for 200 items, it will be pp_out[0] to pp_out[199]. pp_out[200] is out of bounds. Run it in valgrind and it will tell you.
    I wish that was the problem, but all values other than pp_out[0] result in seg fault--and I am actually allocating 200 + 1. I'll sit down to today and run it in valgrind. Thanks

  9. #9
    Join Date
    Jun 2007
    Location
    Maryland, US
    Beans
    6,237
    Distro
    Kubuntu

    Re: segmentation fault--and I think I own the memory

    When receiving data from the "unknown", never use strcpy(). Use strncpy() so that you can limit how much data is copied to the destination. Otherwise you could inadvertently receive a long source string that will overrun your destination buffer, and subsequently cause your application to crash.

    [Content edited... my analysis was incorrect.]

    Consider the following, untested code:
    Code:
    typedef struct
    {
       char field_name[25];
       char field_value[25];
    } DB_Result;
    ...
    static int callback(void* result, int num_col, char** col_text, char** col_name)
    {
       int i = 0;
       DB_Result** db_result = (DB_Result**) result;
    
       for(i = 0; i < num_col; i++)
       {
          strncpy((*db_result)[i].field_name, col_name[i], sizeof((*db_result)[i].field_name));
          strncpy((*db_result)[i].field_value, col_text[i], sizeof((*db_result)[i].field_value));
       }
    
       return 0;
    }
    
    static int cb_create_container(void* result, int num_col, char** col_text, char** col_name)
    {
       DB_Result** db_result = (DB_Result**) result;
       int num_rec;
       int status = -1;
    
       if (db_result && col_text && *col_text)
       {
          if (sscanf(col_text[0], "%d", &num_rec) == 1 && num_rec > 0)
          {
             *db_result = calloc(num_rec, sizeof(DB_Result));
    
             if (*db_result)
             {
                status = 0;
             }
          }
       }
       
       return status;
    }
    Last edited by dwhitney67; September 1st, 2011 at 08:14 PM.

  10. #10
    Join Date
    Mar 2009
    Location
    pennslyvania
    Beans
    122
    Distro
    Ubuntu 10.10 Maverick Meerkat

    Re: segmentation fault--and I think I own the memory

    @dwhitney67

    Thank you--you are very smart. I will not have time till later tonight to figure out what I was doing wrong; but your suggestions were obviously correct.

    Again thank you.
    Last edited by audit; September 1st, 2011 at 06:24 PM.

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •