C: Массив и отрицательный индекс

Модератор: Модераторы разделов

Ответить
Аватара пользователя
Janik
Сообщения: 850
Статус: Оператор вычислительных машин
ОС: Debian

C: Массив и отрицательный индекс

Сообщение Janik »

Что происходит, когда индекс массива - отрицательное число?
Кто ищет, тот всегда найдет!
Опыт - это когда все получается с первого раза.
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C: Массив и отрицательный индекс

Сообщение NickLion »

Смещаемся назад в памяти относительно начала массива, ведь на самом деле 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;
Спасибо сказали:
Аватара пользователя
Janik
Сообщения: 850
Статус: Оператор вычислительных машин
ОС: Debian

Re: C: Массив и отрицательный индекс

Сообщение Janik »

Ну, у меня в этом примере выводятся цифры 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]);
}
Кто ищет, тот всегда найдет!
Опыт - это когда все получается с первого раза.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: C: Массив и отрицательный индекс

Сообщение drBatty »

Janik писал(а):
17.07.2013 17:46
Что происходит, когда индекс массива - отрицательное число?

тоже самое, кода и положительное. В C/C++

Код: Выделить всё

a[i] === *(a+i) === i[a]

просто написано по разному. a[i] пишут исключительно для удобства понимания.

ЗЫЖ в C++ это не совсем эквивалентно из-за перезагрузки операторов.

Janik писал(а):
17.07.2013 19:43
int array[8]
array[-1]

а это быдлокод и неопределённое поведение.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Janik
Сообщения: 850
Статус: Оператор вычислительных машин
ОС: Debian

Re: C: Массив и отрицательный индекс

Сообщение Janik »

drBatty писал(а):
17.07.2013 21:20
а это быдлокод и неопределённое поведение.

Это чисто для эксперимента сделал. Обещаю никогда не использовать это. :D
Кто ищет, тот всегда найдет!
Опыт - это когда все получается с первого раза.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: C: Массив и отрицательный индекс

Сообщение drBatty »

Janik писал(а):
17.07.2013 21:58
Обещаю никогда не использовать это.

дык в ваших интересах не получать канделябром по голове ;)

Опасность такого кода в том, что он легко проходит все тесты, и ломается исключительно в продакшене. В самый ответственный момент ЧСХ.

Причём дело вовсе не только в рандомном результате, ваш быдлокод может ВСЁ завалить. Вот пруф:

Shell

$ cat sf.c int main() { int a[100500]; return a[-99999]; } $ gcc -Wall sf.c $ ./a.out Ошибка сегментирования

http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
BratSinot
Сообщения: 812
ОС: Slackware64

Re: C: Массив и отрицательный индекс

Сообщение BratSinot »

А разве a[-1] не будет чем-то вроде a[2^32-1] (или 2^64-1 если на 64-битной машине)?
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C: Массив и отрицательный индекс

Сообщение NickLion »

Нет. Это именно вычитание из адреса.
Спасибо сказали:
Аватара пользователя
Rootlexx
Бывший модератор
Сообщения: 4455
Статус: GNU generation
ОС: Debian GNU/Linux

Re: C: Массив и отрицательный индекс

Сообщение Rootlexx »

BratSinot писал(а):
08.09.2013 21:26
А разве a[-1] не будет чем-то вроде a[2^32-1] (или 2^64-1 если на 64-битной машине)?

http://stackoverflow.com/a/3473684
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: C: Массив и отрицательный индекс

Сообщение drBatty »

BratSinot писал(а):
08.09.2013 21:26
А разве a[-1] не будет чем-то вроде a[2^32-1] (или 2^64-1 если на 64-битной машине)?

а какая разница? Если вы откроете машинный код (например в отладчике), то увидите, что -1 это и есть 1111 1111 1111 1111 1111 1111 1111 1111. Это для x86, ну а для каких-то хитрых платформ, где это не так, компилятор сам засунет адекватную -1. (в x86 компилятор может и схитрить, используя специальные формы загрузки адреса).

И да, -1 это на самом деле -4 для указателя на int/указатель32, и -8 для указателя на указатель64.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C: Массив и отрицательный индекс

Сообщение NickLion »

drBatty писал(а):
09.09.2013 07:48
а какая разница?

Есть разница, она состоит в том, что операции над указателями — знаковые. Для знаковых операций процедура переполнения — undefined behaviour.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: C: Массив и отрицательный индекс

Сообщение drBatty »

NickLion писал(а):
09.09.2013 10:03
Есть разница, она состоит в том, что операции над указателями — знаковые. Для знаковых операций процедура переполнения — undefined behaviour.

а откуда тут "переполнение"? -1 это всего лишь в одной единице от нуля.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: C: Массив и отрицательный индекс

Сообщение NickLion »

Переполнение, если понимать как p+232-1
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: C: Массив и отрицательный индекс

Сообщение drBatty »

NickLion писал(а):
09.09.2013 11:26
Переполнение, если понимать как p+232-1

ну я всё равно не понял, что имеется ввиду в этом посте: C: Массив и отрицательный индекс
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Ответить