LINUX.ORG.RU

анекдот с массивом


0

0

Собственно, не вопрос - а заметки, и удивление...

В C - захотел сделать массив в структуре, естественно, с фиксированной длиной - прекрасно по задаче подходил:

struct ctx_t {

u16 cache[64];

};

- примерно так. GCC, 3.X - прекрасно скомпилировал, никаких варнингов не выдал - но! В результате, cache стал указателем, указывающим неизвестно куда...

Вылечилось динамическим выделением памяти, но так и не понял я, в чем же тут был "прикол" - такое затворщицкое поведение компилятора...

★★★
Ответ на: комментарий от anonymous

Странно...

В Си есть таки массивы. Должно работать. Память выделяться ДОЛЖНА. Может фича (баг?) компилятора? Единственное, что может еще стоит проверить - ключи компиляции. Возможно какой-то ключик и приводит к такому поведению компилятора?

anonymous
()
Ответ на: Странно... от anonymous

И еще. Тут ты не показал как ты используешь массив. Может быть ошибка там? Потому как приведенный фрагмент ничего подозрительного не включает в себя. Нужен фрагмент, где проявляется ошибка.

anonymous
()
Ответ на: Странно... от anonymous

Какому поведению? Оно и должно быть указателем, всё верно. Массивов нет и не надо. Зачем он полез динамически память выделять - не ясно.

anonymous
()
Ответ на: комментарий от anonymous

> Какому поведению? Оно и должно быть указателем, всё верно.

Мне кажется что ключевое тут "стал указателем, указывающим _неизвестно_ _куда_ ...". Хотя есть версия, что неизвестно это только автору вопроса.

anonymous
()
Ответ на: комментарий от anonymous

Я эту версию сразу принял за основную. Аффтара явно смутило, что массив - это, оказывается, указатель. :)

anonymous
()
Ответ на: комментарий от anonymous

Совершенно верно - указатель. Так же верно, как и то, что память под массив вида xx[yy] должна была выделиться в любом случае. Другой вопрос, что spectr (наверное) ожидает, что она выделиться там же, где лежит структура (внутри структуры). Или я неправильно понимаю постановку вопроса? Спектр, так что же ты хотел спросить? :)

anonymous
()
Ответ на: комментарий от anonymous

Странно - сейчас проверил, все должно работать:

struct ctx_t {
unsigned long cache[64];
unsigned char z;
};

int main(void) {
struct ctx_t *t;
printf("sof == %d\r\n", sizeof(struct ctx_t));
t = (struct ctx_t *)malloc(sizeof(struct ctx_t));
printf("t == 0x%08X\r\n", t);
printf("&t->cache[0] == 0x%08X\r\n", &t->cache[0]);
printf("&t->cache[64] == 0x%08X\r\n", &t->cache[64]);
printf("&t->z == 0x%08X\r\n", &t->z);
return 0;
}

sof == 260
t == 0x0804A008
&t->cache[0] == 0x0804A008
&t->cache[64] == 0x0804A108
&t->z == 0x0804A108

Spectr ★★★
() автор топика
Ответ на: комментарий от Spectr

Проверил - на целевой платформе ведет себя также. Проблемы были в kernel-space, сегодня ещё протестирую.

Сорри, если что - как обычно, опишешь проблему, и сам поймешь, куда копать, чтобы разобратся.

Spectr ★★★
() автор топика
Ответ на: комментарий от Spectr

вот

Поведение программы абсолютно правильное.

&t->cache[0] и t указывают на один и тот же адрес, начало структуры.
&t->cache[64] имеет оффсет относительно &t->cache[0], равный 0x100, это будет 256. И правда - в поле cache у нас 64*4=256 байт, т.к. unsigned long на 32-битных процессорах занимает 4 байта.
t->z и правда указывает туда же, что и &t->cache[64], так как это 65-ый элемент массива, такой указатель за рамками массива, где и начинается t->z.

Что тут непонятного?

Spectrum
()
Ответ на: комментарий от anonymous

Молодой человек, как по Вашему работает оператор sizeof и почему для "указателей" одного типа он выдает 4 (на 32-х битной платформе) , а для иных "указателей" (на 32-х битной платформе) - не 4 ?

Если Вы захотите процитировать Кернигана и Ритчи, 2-е издание, страницу 100 (в оригинале), то потрудитесь, пожалуйста заглянуть, также и на страницу 99.

omerm
()
Ответ на: комментарий от omerm

sizeof, деточка, исключение из правил, и к системе типов языка отношения не имеет вообще и в принципе.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.