1 Востаннє редагувалося Dopamine (19.02.2015 18:56:04)

Тема: Двовимірний динамічний масив

Створюючи програму спіткнувся на цікавий момент. Створюючи місце в пам'яті для майбутнього динамічного масиву 5х5 програма може виводити з масиву число координатою 5х[любе число більше за 5], це правильно чи я щось не так зробив?

#include <iostream>
using namespace std;

void main()
{
    int i, j, kil = 5, key = 0, value, ciferka, newkil;
    
    int **silmas = new int *[kil]; 
    for (i = 0; i < kil; i++)
        silmas[i] = new int[kil];
    
    for (i = 0; i < kil; i++)
    {
        for (j = 0; j < kil; j++)
        {
            silmas[i][j] = 0;
            cout << silmas[i][j] << "\t";
        }
        cout << endl;
    } 
     cout << "\n dobaviti riadok(1) chi stovbec(2)?";    
    while (key != 1 && key != 2)
    {
        cin>>key;
        if (key != 1 && key != 2)
            cout << "\nTry again!\n";
    }
    
        switch (key)
    {
        case 1: 
            cout << "\n riadok. Which stolbec in new riadok u want to fill? \n";
            cin >> value;
            cout << "ciferka?:"; cin >> ciferka;

                        newkil = kil+1; 
                        silmas = new int *[newkil];
                        for (i = 0; i < newkil; i++)
                            silmas[i] = new int[kil];    

                        for (i = 0; i < 6; i++)
                        {
                            for (j = 0; j < 5; j++)
                            {
                                if (j == value-1&&i == 5)
                                {
                                    silmas[i][j] = ciferka;
                                    cout << silmas[i][j] << "\t";
                                }
                                else
                                {
                                    silmas[i][j] = 0;
                                cout << silmas[i][j] << "\t";
                                }

                            }
                            cout << endl;
                        } 
                         
                        cout << silmas[3][38] << "\t"; //  ___________________Чому це працює???
            break;
        case 2:
            cout << "\n stovbec. Which riadok in stovbec u want to fill? \n";
            cin >> value;
            break;
        default: cout << "\nerror\n";
            break;
    }             
    system("pause");
}

2

Re: Двовимірний динамічний масив

Справді, можна взяти сішний масив і вказати індекс елемента за його межами — це не призведе до автоматичної зупинки програми з виводом помилки, бо помилка буде тихою. Так можна читати дані з пам'яті, що безпосередньо в масив не входять, і навіть робити несанкціонований запис туди. Вірніше, на рівні операційної системи такий несанкціонований доступ відстежується, але система бачить не все. Якщо розмір масиву менший за розмір динамічно виділеного для нього блоку пам'яті, то індекс, більший за розмір масиву, але менший за розмір блоку, помилки, ймовірно, не викличе.

Подякували: koala, Dopamine2

3

Re: Двовимірний динамічний масив

Вітаю, ви познайомилися з поняттям UB (undefined behavior, невизначена поведінка). UB - це коли програма буде виконана, але як - суттєво залежить від системи, компілятора і простої удачі. Так, читати дані з невизначених змінних, за випадковими посиланнями (зокрема - за межами масивів) і змінювати одну змінну два рази в одному виразі (наприклад, i =++i + ++i) - це UB. Може, спрацює так, як ви очікуєте, може, випаде з помилкою, а може спрацює зовсім не так.
UB залишають в мові, бо перевірка займає час і ресурси; якщо програмісту вона потрібна - поставить, а якщо важливіший час - то треба писати акуратніше.

Подякували: 0xDADA11C7, Dopamine2