C: Массив и отрицательный индекс
Модератор: Модераторы разделов
-
- Сообщения: 855
- Статус: Оператор вычислительных машин
- ОС: Debian
C: Массив и отрицательный индекс
Что происходит, когда индекс массива - отрицательное число?
Кто ищет, тот всегда найдет!
Опыт - это когда все получается с первого раза.
Опыт - это когда все получается с первого раза.
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: C: Массив и отрицательный индекс
Смещаемся назад в памяти относительно начала массива, ведь на самом деле x[i] === *(x+i). Если массив статический, то затрагиваем стек. Если динамический, то попадаем неизвестно куда. С другой стороны, если указатель указывает не на начало данных, то такое может быть вполне легальным. Например:
Код: Выделить всё
int* p = (int*)malloc(100*sizeof(int)); // C++: new int[100];
int* x = p + 50;
x[-50] = 30; // === p[0] = 30;
Спасибо сказали:
-
- Сообщения: 855
- Статус: Оператор вычислительных машин
- ОС: Debian
Re: C: Массив и отрицательный индекс
Ну, у меня в этом примере выводятся цифры 2 и 0.
Ну, вроде понятно.
Ну, вроде понятно.
Код: Выделить всё
#include <stdio.h>
int array[8] = {1,2,3,4,5,6,7,8};
void main (void)
{
printf ("array[1]=%d\n", array[1]);
printf ("array[-1]=%d\n", array[-1]);
}
Кто ищет, тот всегда найдет!
Опыт - это когда все получается с первого раза.
Опыт - это когда все получается с первого раза.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: C: Массив и отрицательный индекс
тоже самое, кода и положительное. В C/C++
Код: Выделить всё
a[i] === *(a+i) === i[a]
просто написано по разному. a[i] пишут исключительно для удобства понимания.
ЗЫЖ в C++ это не совсем эквивалентно из-за перезагрузки операторов.
а это быдлокод и неопределённое поведение.
-
- Сообщения: 855
- Статус: Оператор вычислительных машин
- ОС: Debian
Re: C: Массив и отрицательный индекс
Это чисто для эксперимента сделал. Обещаю никогда не использовать это.
Кто ищет, тот всегда найдет!
Опыт - это когда все получается с первого раза.
Опыт - это когда все получается с первого раза.
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: C: Массив и отрицательный индекс
дык в ваших интересах не получать канделябром по голове ;)
Опасность такого кода в том, что он легко проходит все тесты, и ломается исключительно в продакшене. В самый ответственный момент ЧСХ.
Причём дело вовсе не только в рандомном результате, ваш быдлокод может ВСЁ завалить. Вот пруф:
Shell
$ cat sf.c
int main()
{
int a[100500];
return a[-99999];
}
$ gcc -Wall sf.c
$ ./a.out
Ошибка сегментирования
-
- Сообщения: 812
- ОС: Slackware64
Re: C: Массив и отрицательный индекс
А разве a[-1] не будет чем-то вроде a[2^32-1] (или 2^64-1 если на 64-битной машине)?
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: C: Массив и отрицательный индекс
Нет. Это именно вычитание из адреса.
-
- Бывший модератор
- Сообщения: 4456
- Статус: GNU generation
- ОС: Debian GNU/Linux
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: C: Массив и отрицательный индекс
а какая разница? Если вы откроете машинный код (например в отладчике), то увидите, что -1 это и есть 1111 1111 1111 1111 1111 1111 1111 1111. Это для x86, ну а для каких-то хитрых платформ, где это не так, компилятор сам засунет адекватную -1. (в x86 компилятор может и схитрить, используя специальные формы загрузки адреса).
И да, -1 это на самом деле -4 для указателя на int/указатель32, и -8 для указателя на указатель64.
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: C: Массив и отрицательный индекс
а откуда тут "переполнение"? -1 это всего лишь в одной единице от нуля.
-
- Сообщения: 3408
- Статус: аватар-невидимка
- ОС: openSUSE Tumbleweed x86_64
Re: C: Массив и отрицательный индекс
Переполнение, если понимать как p+232-1
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current