2012-03-30 2 views
1

У меня есть следующий код: (прошу прощения за длину этого кода). Я пытаюсь получить доступ к элементам вектора внутри вектора. table_info * Функция get_table_info получает значения вектора table_info для конкретной таблицы. Когда я пытаюсь проверить значения вектора column_info, я сталкиваюсь с странной ошибкой, когда программа внезапно завершается.Аномальная ошибка завершения программы при доступе элементов при использовании вектора внутри вектора в C++

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; 
    } 

Любая идея, почему эта программа завершается? Пожалуйста помоги.

+0

Я предполагаю, что это на Windows? Я думаю, что «ненормальное завершение программы» - это неперехваченное исключение, вероятно, выведенное «vector :: at», потому что «i» выходит за пределы диапазона. Однако, что бы это ни было, возможно, с легкостью можно легко отлаживать отладчик. – netcoder

+0

Да, это на окнах, и я попытался отладить использование eclipse. Но отладчик просто внезапно остановился на линии. Значение num_col в порядке. Я проверил его, поэтому я не думаю, что это потому, что значение i выходит за пределы. Любые другие предложения действительно помогут. – PGOnTheGo

ответ

0

Проблема в том, что этот код:

v.push_back(new_table); 

вызывается до того, как столбцы добавляются в таблицу. В это время «col» -собор пуст. Затем push_back выталкивает копию вашего экземпляра table_info на вектор (конечно, с пустым col -vector). Поэтому, если вы добавляете столбцы, он не добавляется к экземпляру в вашем векторе, а вместо этого локальному экземпляру.А поскольку num_col больше нуля он бросает исключение, если вы пытаетесь получить доступ к столбцы на этой линии, так как table_info является экземпляр, который хранится в векторе (один с пустым col):

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

решение переместить push_back код вниз, прямо перед вызовом get_table_info (или после добавления столбцов, если вы будете):

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

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

Спасибо, vstm. Это сработало! Я забыл что-то столь важное. – PGOnTheGo

1

У вас есть:

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; 
    ... 
} 

но get_table_info() может возвращать NULL, так что вы можете быть разыменования указателя NULL (с ​​->). Вам тоже нужно справиться с этим делом!

Другая возможность может быть частью col.at (i), вы уверены, что я между 0 и col.size() - 1? Обратите внимание, что это полностью зависит от параметра num_col!

0

Это трудно сказать, не весь код, но похоже, что вы на самом деле не всегда назначать данные элемента «перевалы» в структуры:

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

Это может быть возможно, вы присваиваете num_col после выражения 'for' и никогда не назначая значения. Тем не менее, я не могу сказать, с помощью сегментов, которые вы вставляете здесь. Вам необходимо предоставить фактическое содержимое исходного файла.

Вы также должны поместить больше ошибок в свой код. В частности, область Вы столкнулись с проблемой:

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

Проверьте размер вектора, прежде чем пытаться получить доступ к col.at (I). Добавьте некоторые инструкции printf/cout в stdout, если что-то отключено. В противном случае, использовать известный регистратор:

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

Это поможет решить проблемы в вашем коде быстрее.

Еще одна вещь, чтобы проверить, как код связывается и ссылается. Являются ли эти структуры в одном источнике с C++? Вы связываетесь с внешними библиотеками c и ссылаетесь на эти заголовки? Возможно, вам придется проверить и скомпенсировать выравнивание байт, поместите структурированные вами структуры.

Смежные вопросы