Запись цикла массива поверх элементов C

#c #arrays #for-loop

#c #массивы #for-цикл

Вопрос:

Я записываю в массив из цикла внутри цикла. Значения записываются поверх самих себя.

Пара справочных заметок — keyname = GET_STRING_VALUE(Ds, Os, Fs, Rs, Is); это извлечение строковых значений из базы данных. Примером может быть 71001093 . Эти ключи будут разными для каждого Rs (номер записи для этой базы данных). Fk И Fs относятся к разным столбцам в этой базе данных. Предполагается, что код перебирает (первые 5) записей базы данных и находит имя, связывающее его с ключом. Для имен, которые соответствуют keycmp, добавьте их в массив.

Проблема

Распечатки ArrayCheck внизу отображают последний ключ, введенный в массив. На распечатке ключа и счетчика отображается правильный номер итерации и связанный с ним ключ в цикле.

Код

 char* status_keys [ 2 ][ 200 ];
int Ds, Os, Fs, Rs, Is, Fk, a, c;
char* keyname;
char* keycmp;
char* stationlookup[4];
char* key;

keycmp = "STRING";
for ( Rs = 1; Rs < 5; Rs   ) {

    keyname = GET_STRING_VALUE(Ds, Os, Fs, Rs, Is);

    printf("keyname: %sn", keyname);

do {
        strncpy(stationlookup, keyname, 4);
        stationlookup[4] = '';

        key = GET_STRING_VALUE(Ds, Os, Fk, Rs, Is);
        printf("key : %sn",key);
        printf("counter : %dn",a);


        status_keys[0][a] = key;
        status_keys[1][a] = stationlookup;

        a  ;

    } while (strstr(keyname,keycmp) != NULL);

}

printf("ArrayCheck 0: %sn", status_keys[0][0]);
printf("ArrayCheck 1: %sn", status_keys[0][1]);
printf("ArrayCheck 2: %sn", status_keys[0][2]);    
printf("ArrayCheck 3: %sn", status_keys[0][3]);
 

Пример вывода:
введите описание изображения здесь

Ценю stationlookup помощь, но этот код по-прежнему обеспечивает перезапись проблемы.

 for ( Rs = 1; Rs < 5 ; Rs   ) {

keyname = GET_STRING_VALUE(Ds, Os, Fs, Rs, Is);

printf("keyname: %sn", keyname);

do {
        status_keys[0][a] = GET_STRING_VALUE(Ds, Os, Fk, Rs, Is);
        printf("key : %sn",status_keys[0][a]);
        printf("counter : %dn",a);
        a  ;

    } while (strstr(keyname,keycmp) != NULL);

}
 

Комментарии:

1. Можете ли вы дать нам пример запуска / вывода? Я не уверен, в чем проблема. Я знаю, что вы, вероятно, имеете в виду использовать strlcpy вместо strncpy . Кроме того, вы, похоже, выполняете «мелкую копию», а не «глубокую копию» при назначении status_keys[0][a] = key; и status_keys[1][a] = stationlookup; .

2. Может быть, проблема с указателем? Попробуйте установить status_keys[0][a] в GET_STRING_VALUE напрямую, чтобы избежать использования ключевой переменной. Это, по крайней мере, сообщит вам, есть ли проблема с указателем с ключом.

3. Flyingcows00 — та же проблема с status_keys[0][a] = GET_STRING_VALUE(Ds, Os, Fk, Rs, Is);

4. что касается этой строки: char* stationlookup[4]; Он определяет 4 указателя на строки, а не массив из 4 символов.

5. что касается этой строки: stationlookup[4] = »; Она записывается в указатель на 5-й символ, однако в массиве указателей символов есть только указатели на 4 символа: stationlookup

Ответ №1:

Вы заявили:

 char* stationlookup[4];
 

Это означает , что допустимыми показателями являются [0] , [1] , [2] и [3] .

Итак, строка кода, подобная этой:

 stationlookup[4] = '';
 

создает переполнение массива.

Комментарии:

1. Хороший улов, но если я полностью удалю stationlookup и strncpy у меня все еще будет та же проблема.

Ответ №2:

Я подозреваю, что ваши проблемы возникают из этих строк:

     status_keys[0][a] = key;
    status_keys[1][a] = stationlookup;
 

предполагая, что GET_STRING_VALUE() это возвращает один и тот же указатель на строку при каждом вызове. Приведенные выше строки не копируют строки, а вместо этого копируют указатели на строки, что приводит к тому, что элементы вашего массива перезаписываются. Вы можете проверить это, напечатав значение указателя с помощью:

    printf("keyptr : %pn", key);
 

Чтобы исправить это, вам нужно изменить свой код на что-то вроде:

    char status_keys [ 2 ][ 200 ][64];
   ...
   strncpy(status_keys[0][a], key, 62); // or strlcpy() if you have it
   strncpy(status_keys[1][a], stationlookup, 62);
 

или что-то вроде:

    char* status_keys [ 2 ][ 200 ];
   ...
   status_keys[0][a] = malloc(strlen(key) 1); 
   strcpy(status_keys[0][a], key);

      // Same for stationlookup
      // Make sure to free() the strings at some point
 

если вы предпочитаете динамический доступ к памяти.

Комментарии:

1. Спасибо uesp, отличное объяснение и примеры.