#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, отличное объяснение и примеры.