1

I have the following code: (please pardon the length of this code). I am trying to access elements of a vector within a vector. table_info* get_table_info function gets the values of the table_info vector for a particular table. When I try to check the values of column_info vector, I an encountering a strange error, where the program suddenly terminates.

typedef struct _column_info {
char name[20];  // columns name
int type; // 0:INT, 1: CHAR
int size;
int offset; // start position
} column_info;

typedef struct _table_info {
char name[20];
int column_count;
char columns[100];
vector <column_info> col;   //col[0], col[1]...
char primary_key[5];
int recordsize;
int totalsize;
int records;
} table_info;

vector <table_info> v;

void create_table(char* tablename, struct columns *cc , int num_col, char* pkey) {
    char* new_columns;
new_columns = (char*)malloc(256*sizeof(char));
strcpy(new_columns,"");

int len = 0;
len = num_col;

for ( int i=0 ; i < len ; i++ )
{
    strcat(new_columns, cc[i].c_name);
    strcat(new_columns, ":");
    strcat(new_columns, cc[i].c_type);

    if ( strcmp(cc[i].c_type,"char") == 0 )
    {
        strcat(new_columns, "(");
        strcat(new_columns, cc[i].c_size);
        strcat(new_columns, ")");
        record_size = record_size + atoi(cc[i].c_size);
    }
    else
        record_size = record_size + 4;

    if( i != (len-1) )
        strcat(new_columns, ",");
}

    table_info new_table;

        strcpy(new_table.name, tablename);
        strcpy(new_table.columns, new_columns);
        strcpy(new_table.primary_key, pkey);
        new_table.recordsize = record_size;
        new_table.totalsize = 0;
        new_table.records = 0;

        v.push_back(new_table);

    column_info cols;
    int offset = 0;
    for(int x=0;x<num_col;x++)
    {
        strcpy(cols.name, cc[x].c_name);
        if ( strcmp(cc[x].c_type,"char") == 0 )
            cols.type = 1;
        else
            cols.type = 0;
        cols.size = atoi(cc[x].c_size);

        cols.offset = offset;
        offset += cols.size;

        new_table.col.push_back(cols);
    }

table_info* table_info;
    table_info = get_table_info(tablename);
    int offset2=0;
    int size2 = 0;

    for (int i = 0; i < num_col ; i++)
    {
     offset2 = table_info->col.at(i).offset; // ERROR: ABNORMAL PROGRAM TERMINATION
      printf("offset:%d\n",offset2);
      size2 = table_info->col.at(i).size;
    }
    }

table_info* get_table_info(const string& tablename)
{
printf("table info \n");
    for (int i = 0; i < (int) v.size(); i++)
     {
       if (strcmp(v.at(i).name, tablename.c_str()) == 0)
    return &v.at(i);
     }
     return NULL;
  }

Any idea why this program terminates? Please help.

2
  • I assume this is on Windows? I think "abnormal program termination" is an uncaught exception, probably thrown by vector::at because i is out of range. Whatever it is however, it can probably be fixed easily with a debugger. Commented Mar 30, 2012 at 15:38
  • Yes this is on windows, and I did try to debug using eclipse.But the debugger just suddenly stopped at the line. The value of num_col is okay. I have checked it, so I dont think it is because the value of i is out of bounds. Any other suggestions would really help. Commented Mar 30, 2012 at 15:54

3 Answers 3

1

You have:

table_info* table_info
table_info = get_table_info(tablename);
...
for (int i = 0; i < num_col ; i++)
{
    offset2 = table_info->col.at(i).offset;
    ...
}

but get_table_info() can return NULL, so you may be dereferencing a NULL pointer (with ->). You need to handle this case too!

Another possibility may be the col.at(i) part, are you sure i lies between 0 and col.size()-1? Note this completely depends on the parameter num_col!

Sign up to request clarification or add additional context in comments.

Comments

0

The Problem is that this code:

v.push_back(new_table);

is called before the columns have added to the table. At this time the "col"-collection is empty. Then push_back pushes a copy of your table_info instance to the vector (of course with the empty col-vector). So if you add the columns it is not added to the instance in your vector but to the local instance instead. And since num_col is greater than zero it throws an exception if you try to access the columns on that line, since table_info is the instance which is stored in the vector (the one with the empty col):

offset2 = table_info->col.at(i).offset; // ERROR: ABNORMAL PROGRAM TERMINATION

The solution is to move the push_back code down, right before you call get_table_info (or after adding the columns, if you will):

// ... 
v.push_back(new_table);

table_info* table_info;
table_info = get_table_info(tablename);
// ... 

1 Comment

Thank you vstm. That worked! I was overlooking something so crucial.
0

It's hard to tell without all the code, but it looks like you don't actually ever assign data to the "cols" member in struct:

for(int x=0;x<num_col;x++)

It could be possible you're assigning num_col after the 'for' statement and never actually assigning values. However, I can't tell with the segments you've pasted here. You need to provide the actual source file content.

You should also place more error checking in your code. Specifically, the area you're encountering a problem:

offset2 = table_info->col.at(i).offset; 

Check the size of the vector before you try to access col.at(i). Add some printf/cout statements to stdout if something is off. Otherwise, use a known logger:

http://boost-log.sourceforge.net/libs/log/doc/html/log/tutorial/sources.html

This will help resolve issues in your code quicker.

Another thing to check is how code is getting linked and referenced. Are these structs in the same source with c++? Are you linking against external c libraries and referencing these headers? You might have to check and compensate byte alignment, pad the structs you're referencing.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.