Розміщення об'єктів в оперативній пам'яті

Арифметика покажчиків, масиви.

Масиви, оператор індексації, базові операції над покажчиками
Практичні приклади - функції strcpy і strlen
замість висновку
Корисні вправи
Список літератури

Розміщення об'єктів в оперативній пам'яті

За винятком перерахованих, інші арифметичні операції над покажчиками не визначені - їх використання призведе до помилок компіляції програми. Так, помилку компіляції викличе спроба складання двох покажчиків або порівняння покажчиків на об'єкти різного типу, спроба вирахування з покажчика числа з плаваючою точкою і ін. Ті ж арифметичні операції, що можуть застосовуватися до покажчиків, в переважній більшості випадків мають сенс тільки в контексті роботи з масивами (з цієї причини арифметика покажчиків і масиви зазвичай розглядаються одночасно).

Масиви, оператор індексації, базові операції над покажчиками

Масив - це упорядкований набір (колекція) однотипних об'єктів, що розміщуються в єдиному блоці пам'яті послідовно один за одним. Однотипні об'єкти, що входять до складу масиву, називають елементами масиву. Кожному елементу масиву відповідає порядковий номер - індекс. Індексація елементів починається з нуля. початковий (перший) елемент масиву має індекс 0, наступний за ним (другий) - індекс 1, наступний за другим (третій) - індекс 2 і т. д. Останній елемент масиву з k елементів має індекс k - 1.

Розміщення об'єктів в оперативній пам'яті

Мал. 1. Масив з k елементів

Більш конкретно принципи роботи з масивами і базові операції над покажчиками розглянемо на наступному невеликому прикладі.

Масиви, так само як і будь-які інші види об'єктів, можуть бути розміщені як в стеці, так і в динамічної пам'яті. Спочатку розглянемо розміщення масивів в стеці. Код першого рядка функції main виконує таке розміщення:

Відповідно до семантикою оператора індексації, тут здійснюється перехід до об'єкта масиву vec з індексом 2, після чого отриманого об'єкту присвоюється нове значення - в відведені під цей об'єкт осередки пам'яті записується число 103 (рис. 6).


Мал. 7. Покажчик на елемент масиву з k об'єктів

Якщо p вказує на об'єкт, який не є елементом масиву, то результат складання p з цілим числом не визначений (причому до помилки компіляції таке складання не приведе - помилка виникне в процесі виконання програми).

У нашому випадку vec - це покажчик на початковий елемент масиву, отже, при обчисленні виразу vec + 2 ми повинні отримати покажчик на другий після початкового, т. Е. На третій елемент масиву. В умовах наших припущень про розташування об'єктів в пам'яті маємо:

vec + 2 = vec + 2 * sizeof (short) = 0xF838 + 2 * 2 = 0xF838 + 4 = 0xF83C.

Якщо роздрукувати значення елемента масиву з індексом 2 і об'єкта, на який вказує vec + 2:

Наведені вище фрагменти коду є також прикладами випадків, коли неважливо, який саме оператор інкремента - префіксний або постфіксний - використовується для збільшення значення змінної. У цих фрагментах оператор інкремента потрібен тільки для збільшення значення індексу i. безпосередньо повертається їм значення не використовується.

Можливо, вираз while (* p ++ = * s ++) на перший погляд і здається незрозумілим, однак такий запис зручна, на практиці подібний код зустрічається. Про важливість його розуміння говорить і той факт, що розібраний нами приклад розглянуто також в книзі Бйорна Страуструпа «Мова програмування C ++» [1] і книзі Брайана Керніган і Денніса Рітчі «Мова програмування C» [2]. Додатково про важливість знання аспектів реалізації функції strcpy можна почитати в книгах Джоела Спольскі «Джоел про програмування" [6] і "Джоел: і знову про програмування» [10].

На закінчення розділу розглянемо операцію віднімання одного покажчика з іншого. З використанням даної операції реалізується, зокрема, функція обчислення довжини рядка strlen стандартної бібліотеки C / C ++.

замість висновку

Значна частина помилок при роботі з пам'яттю пов'язана з її витоками, т. Е. З не звільненням або неправильним звільненням раніше виділеної динамічної пам'яті. Зокрема, поширеною помилкою є видалення масиву об'єктів оператором delete замість оператора delete []. Така підміна операторів може ніяк не виявитися при видаленні масиву об'єктів вбудованого типу, але при руйнуванні масиву складних об'єктів, наприклад масиву рядків (об'єктів типу std :: string), використання оператора delete призведе до того, що буде вилучена тільки перший рядок, інші залишаться в пам'яті. Для виявлення помилок подібного роду створені спеціальні інструментальні засоби, одне з яких було розглянуто в першій частині статті.

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

Корисні вправи

  1. Виконайте введення з клавіатури двох цілочисельних масивів, сформуйте і виведіть на екран третій масив, одержуваний вставкою всіх елементів другого масиву після заданого елемента першого.
  2. Виконайте введення з клавіатури двох рядків, сформуйте і виведіть на екран третій рядок, що є конкатенацией введених.

Список літератури

Схожі статті