Search code examples
c++pointerssegmentation-faultcoredumplibpqxx

column number 1 is out of range 0..-1


I wrote a function in which I want to pass a pointer to array of structures. I donew() inside it and I want to fill it with data retrieved from PGresult structure (res). However I got errors:

column number 0 is out of range 0..-1 
column number 1 is out of range 0..-1 
column number 2 is out of range 0..-1 
column number 3 is out of range 0..-1
Segmentation fault (core dumped)

here is my function

Database::selectAnnouncements(const int user_id, const char *cat_id, struct announcementStruct **pStruct, int *size) {

*size = PQntuples(res);

struct announcementStruct * ann = new struct announcementStruct[PQntuples(res)];
*pStruct =  ann;
int cr_fnum = PQfnumber(res, "created_on");
int con_fnum = PQfnumber(res, "content");
int cat_fnum = PQfnumber(res, "category");
int rm_fnum = PQfnumber(res, "remove_on");


for (int i = 0; i < PQntuples(res); i++) {
        const char *cr_val = PQgetvalue(res, i, cr_fnum);
        const char *con_val = PQgetvalue(res, i, con_fnum);
        const char *cat_val = PQgetvalue(res, i, cat_fnum);
        const char *rm_val = PQgetvalue(res, i, rm_fnum);
        (*pStruct[i]).creation_date = new char[strlen(cr_val)];
        (*pStruct[i]).content = new char[strlen(con_val)];
        (*pStruct[i]).category = new char[strlen(cat_val)];
        (*pStruct[i]).removal_date = new char[strlen(rm_val)];
        strcpy((*pStruct[i]).creation_date, cr_val);
        strcpy((*pStruct[i]).content, con_val);
        strcpy((*pStruct[i]).category, cat_val);
        strcpy((*pStruct[i]).removal_date, rm_val);
}

for (int i = 0; i < PQntuples(res); i++) {
        printf("%s  ", (pStruct[i]->creation_date));
        printf("  %s  ", (pStruct[i]->content));
        printf("  %s  ", (pStruct[i]->category));
        printf("  %s  ", (pStruct[i]->removal_date));
        printf("\n");
}
PQclear(res);

}

here is how I use it

struct announcementStruct *announcements = NULL;
int size;
db.selectAnnouncements(0, "DOGS", &announcements, &size);

Solution

  • You are definitely forgetting to null terminate the strings. Allocate strlen + 1 to fit the null. Forgetting a null is an easy cause of segfaults. Functions like strncpy snprintf help ensure things are safer.

    The comment by Kevin is also correct. Make sure you get all 12 instances of this mistake (the original 4, the four in the strcpy and the 4 in the printf)