Ujemna wartość indeksu tablicy

0

Witam!

Patrzcie jakiego buga znalazłem dzisiaj w C, powinienem za to dostać z milion dolarów.

#include <stdio.h>

int main()
{
    int i = -1;
    int o[1000];
    
    o[i] = 100;
    printf("%d\n", o[-1]);
    return 0;
}
7

To nie jest bug.

To jest zdefiniowane w specyfikacji C, jako undefined behaviour.

2
ProgrammingKing napisał(a):

Witam!

Patrzcie jakiego buga znalazłem dzisiaj w C, powinienem za to dostać z milion dolarów.

No biznes w tym jest. Wiele milionów(miliardów?) dolarów już poszło na inwestowanie w języki memory safe (od kilku lat hype'owany jest Rust), które chronią m.in. przed takimi właśnie dziwnymi rzeczami.

1

Ale że tak po omacku programujesz nie rozumiejąc co piszesz?

Może liczba -1 wygląda dziwnie, ale to jest równoważne 0 - 1, i teraz jak sobie w tabelce jak w podstawówce policzysz, to wyjdzie, że będziesz musiał pożyczać w nieskończoność bo masz.
(32bity) 00000000000 - 1, to pożyczasz pożyczasz pożyczasz, czyli masz jedną magiczną jedynkę z przodu 10000000 - 1, czyli coś podobnego do 1000 - 1 w dziesiętnym to będzie 999, a w bitowym same 1111111111

Czyli twoje i wynosi: printf("%u\n", i); potraktowane jako unsigned.

A w bitach w C++ to byś odczytał tak.

int i = -1;
#include <bitset>
std::bitset<32> j(i);
std::cout << j << std::endl;
3
tumor napisał(a):

Ale że tak po omacku programujesz nie rozumiejąc co piszesz?

Może liczba -1 wygląda dziwnie, ale to jest równoważne 0 - 1, i teraz jak sobie w tabelce jak w podstawówce policzysz, to wyjdzie, że będziesz musiał pożyczać w nieskończoność bo masz.
(32bity) 00000000000 - 1, to pożyczasz pożyczasz pożyczasz, czyli masz jedną magiczną jedynkę z przodu 10000000 - 1, czyli coś podobnego do 1000 - 1 w dziesiętnym to będzie 999, a w bitowym same 1111111111

No nie bardzo o to chodzi, po prostu arytmetyka wskaźników jest odwracalna o[1] czy o[0 + 1] to to samo co 0[o + 1] czyli po prostu wartość z pamięci o adresie o przesuniętym o 1, tak samo można wziąć po prostu adres o 1 mniejszy. Tu na przykład możesz zrobić tablicę b, potem wskaźnik c wskazujący na środek tej tablicy, a potem odwołać się do c[-1] lub 0[c - 1] i w ten sposób weźmiesz element z lewej strony od środka tablicy

#include <stdio.h>

int main()
{
	int b[10];
    b[4] = 69;
    b[3] = 42;
    int* c = &b[5];

    printf("%d\n", c[-1]); // 69
    printf("%d\n", 0[c - 1]); // 69
    printf("%d\n", c[-2]); // 42
    printf("%d\n", 0[c - 2]); // 42
    return 0;
}

o[-1] po prostu modyfikuje losową wartość w pamięci zależy od kompilatora i jak się zmienne ułożą

2

Dzięki, dzwoniłem juz do komisji standaryzacyjnej z tym problemem, teraz tylko formalności i w następnym tygodniu wypłacają mi nagrodę

1 użytkowników online, w tym zalogowanych: 0, gości: 1