![]() |
Здравствуйте, гость ( Вход | Регистрация )
![]() ![]() |
![]() |
rp80 |
![]()
Сообщение
#1
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Копирование указателя на объект не приводит к копированию объекта.
Значит следующий код приведет к утечки памяти:
Правильно копировать так:
А что происходит при копировании переменных в стеке?
Теряется ли память выделенная первоначально под s? |
|
|
Алексей1153 |
![]()
Сообщение
#2
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2944 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
Правильно копировать так: char* c =new char[30]; char* cc="zca"; delete[] c; c=new char[sizeof(cc)]; for(size_t i=0;i<sizeof(cc);++i) c[i]=cc[i]; лучше уж так
А что происходит при копировании переменных в стеке? const char* s="xzczv"; const char* s1="vvb"; s=s1;//s и s1 указывают на одно и тоже место в памяти здесь массивы заданы статически , они являются константами. Причём на стеке - только указатели, сами данные в странице данных Ничего никуда не утечёт |
|
|
BRE |
![]()
Сообщение
#3
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
Iron Bug |
![]()
Сообщение
#4
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
rp80 |
![]()
Сообщение
#5
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
лучше уж так
Ага, можно и так. здесь массивы заданы статически , они являются константами. Причём на стеке - только указатели, сами данные в странице данных Ничего никуда не утечёт А можно поподробнее что за страница данных,какая разница константы они или нет? Разве если просто char* без const написать что-то изменится в работе с памятью? Потом даже если в стеке только указатели, но сами-то данные должны тоже где-то хранится, соответственно под них выделена где-то память, что с этой памятью происходит в момент копирования? Ну или где почитать про это. Не получается ничего толкового нагуглить А что происходит при копировании переменных в стеке? после выхода из функции стек будет почищен от временных переменных. так что ничего не теряется. но и смысла особого в этом нет. Понятно, что при выходе почистится стек, но если в блоке (функции) мы создадим массив на 2гб и он при таком копировании потеряется, то на следующий уже может не хватить места. |
|
|
Iron Bug |
![]()
Сообщение
#6
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Понятно, что при выходе почистится стек, но если в блоке (функции) мы создадим массив на 2гб и он при таком копировании потеряется, то на следующий уже может не хватить места. ну, какбэ стек не резиновый. и два гигабайта под стек, может, и можно выделить (опцией при компиляции), но нецелесообразно. если собираешься работать с большими массивами - это куча и динамическое размещение. |
|
|
rp80 |
![]()
Сообщение
#7
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
ну, какбэ стек не резиновый. и два гигабайта под стек, может, и можно выделить (опцией при компиляции), но нецелесообразно. если собираешься работать с большими массивами - это куча и динамическое размещение. Да это понятно. Вообще работа со стеком крайне быстра при объеме стека меньше 4кб, а далее все становится медленнее. И советуют в общем случае если функция работает с памятью больше 1 мб, то по-любому выделять память в куче. Но вопрос не в этом ) А в том, что хочется понять что конкретно происходит с памятью при копировании локальных переменных. |
|
|
Iron Bug |
![]()
Сообщение
#8
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Но вопрос не в этом ) А в том, что хочется понять что конкретно происходит с памятью при копировании локальных переменных. при копировании переменных данные копируются. а тут ты просто манипулируешь указателями на область данных (ибо константы), так что копируются только значения самих указателей. |
|
|
BRE |
![]()
Сообщение
#9
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
rp80 |
![]()
Сообщение
#10
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
при копировании переменных данные копируются. а тут ты просто манипулируешь указателями на область данных (ибо константы), так что копируются только значения самих указателей. Ну вот так вроде понятнее стало. Но все же, чтобы до конца понять ответьте пожалуйста по пунктам. Допустим размер стека 0 байт.
В какое?
Что происходит с данными s? Как освобождается память занимаемая ими? И освобождается ли вообще?
Но данные остаются. т.е. память которую занимали данные на которые указывал s2 не освободилась при уничтожении s2.
Но уничтожаются ли тут данные, на которые указывала s? Ведь выше в аналогичном случае этого не произошло. Спасибо. |
|
|
Iron Bug |
![]()
Сообщение
#11
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
В какое? в сегмент данных. впрочем, может, компилятор для оптимизации их даже в сегмент кода упихивает, ибо константы не меняются, а ближние указатели быстрее. Что происходит с данными s? Как освобождается память занимаемая ими? И освобождается ли вообще? с константными строками ничего не происходит. они остаются. компилятор всё равно выделяет под них место в данных - нет смысла их удалять. во всяком случае, мне не известно о какой-либо хитрой рантайм оптимизации неиспользованных данных. а если это оптимизированное хранение констант в сегменте кода, то их в принципе невозможно удалить. если хочешь, чтобы строки не занимали место - грузи их динамически из какого-то стороннего файла. |
|
|
ilyabvt |
![]()
Сообщение
#12
|
Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 297 Регистрация: 23.6.2011 Пользователь №: 2765 Спасибо сказали: 45 раз(а) Репутация: ![]() ![]() ![]() |
Правильно копировать так:
Не правильно. sizeof(cc) вернет размер указателя, а не массива. В данном случае это сработает только по тому что вы создали 4-х байтный массив. Цитата а если это оптимизированное хранение констант в сегменте кода, то их в принципе невозможно удалить Теоретически возможно. Только это путь даже не джедая, а какого-то безумного ситха, ибо придется не только найти строки в памяти и удалить, но и подредактировать код (не исходный, а тот что висит в памяти в виде процессорных иструкций) так чтобы прога думала что никакой переменной и не существовало. ![]() Сообщение отредактировал ilyabvt - 22.12.2011, 17:50 |
|
|
rp80 |
![]()
Сообщение
#13
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
с константными строками ничего не происходит. они остаются. компилятор всё равно выделяет под них место в данных - нет смысла их удалять. во всяком случае, мне не известно о какой-либо хитрой рантайм оптимизации неиспользованных данных. а если это оптимизированное хранение констант в сегменте кода, то их в принципе невозможно удалить. если хочешь, чтобы строки не занимали место - грузи их динамически из какого-то стороннего файла. Т.е. если где-то в функции мы создаем десять строк по 100 мб, то экзешник будет 1000+ мб? Ну и правильно я понимаю, что строки это не исключение из правил? Значит значения любых базовых или пользовательских локальных переменных и массивов этих переменных сохраняются в коде? Сообщение отредактировал rp80 - 22.12.2011, 19:28 |
|
|
ilyabvt |
![]()
Сообщение
#14
|
Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 297 Регистрация: 23.6.2011 Пользователь №: 2765 Спасибо сказали: 45 раз(а) Репутация: ![]() ![]() ![]() |
с константными строками ничего не происходит. они остаются. компилятор всё равно выделяет под них место в данных - нет смысла их удалять. во всяком случае, мне не известно о какой-либо хитрой рантайм оптимизации неиспользованных данных. а если это оптимизированное хранение констант в сегменте кода, то их в принципе невозможно удалить. если хочешь, чтобы строки не занимали место - грузи их динамически из какого-то стороннего файла. Т.е. если где-то в функции мы создаем десять строк по 100 мб, то экзешник будет 1000+ мб? Ну и правильно я понимаю, что строки это не исключение из правил? Значит значения любых базовых или пользовательских локальных переменных и массивов этих переменных сохраняются в коде? Не забывайте что речь идет о константных строках, т.е. тех значение которых мы явно задаем в программе. Вы часто в исходнике пишете строку длинною 100 миллионов символов? Строки действительно не исключение, числа заданные явно тоже хранятся в коде. Вот например есть код:
Переменная 'а' хранится в стеке, а число 2 в коде. |
|
|
rp80 |
![]()
Сообщение
#15
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Не забывайте что речь идет о константных строках, т.е. тех значение которых мы явно задаем в программе. Вы часто в исходнике пишете строку длинною 100 миллионов символов? Строки действительно не исключение, числа заданные явно тоже хранятся в коде. Вот например есть код:
Переменная 'а' хранится в стеке, а число 2 в коде. Спасибо за пояснение. Ну есстественно, программист сам не задает такие строки. Но, например, строку в которую читают из файла размером в 100 000 000 символов представить вполне можно. Это же тоже явное задание? |
|
|
ilyabvt |
![]()
Сообщение
#16
|
Активный участник ![]() ![]() ![]() Группа: Участник Сообщений: 297 Регистрация: 23.6.2011 Пользователь №: 2765 Спасибо сказали: 45 раз(а) Репутация: ![]() ![]() ![]() |
Не забывайте что речь идет о константных строках, т.е. тех значение которых мы явно задаем в программе. Вы часто в исходнике пишете строку длинною 100 миллионов символов? Строки действительно не исключение, числа заданные явно тоже хранятся в коде. Вот например есть код:
Переменная 'а' хранится в стеке, а число 2 в коде. Спасибо за пояснение. Ну есстественно, программист сам не задает такие строки. Но, например, строку в которую читают из файла размером в 100 000 000 символов представить вполне можно. Это же тоже явное задание? Нет конечно, мало ли что будет в этом файле (и будет ли он вообще) на момент компиляции. А потом, файл вы считываете в переменную. А речь сейчас не о них. Речь о константных данных. Явное задание это то что программист указывает в коде. |
|
|
rp80 |
![]()
Сообщение
#17
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
Нет конечно, мало ли что будет в этом файле (и будет ли он вообще) на момент компиляции. А потом, файл вы считываете в переменную. А речь сейчас не о них. Речь о константных данных. Явное задание это то что программист указывает в коде. Хорошо, а где хранятся данные переменных? В самом стеке? И в примере с чтением из файла в какой-то момент будет переполнение стека, если файл достаточно большой? |
|
|
Iron Bug |
![]()
Сообщение
#18
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Теоретически возможно. Только это путь даже не джедая, а какого-то безумного ситха, ибо придется не только найти строки в памяти и удалить, но и подредактировать код (не исходный, а тот что висит в памяти в виде процессорных иструкций) так чтобы прога думала что никакой переменной и не существовало. ![]() нет. сегмент кода не может менять содержимое ни в одной из современных осей. это главное правило: код не может модифицировать сам себя. это только в DOSе можно было писать такие кренделя. любая защищённая система этого не позволяет. модифицировать можно исполняемый файл, например. или в отладчике писать какие-то значения в регистры. или подгружать какие-то библиотеки на ходу. но сама программа себя менять никак не может. просто нет прав на запись в сегмент кода. Хорошо, а где хранятся данные переменных? В самом стеке? И в примере с чтением из файла в какой-то момент будет переполнение стека, если файл достаточно большой? смотря каких. константы могут быть сложены в сегмент кода (раз они не меняются). переменные, которые обычные - в сегменте данных. можно ещё регистровые переменные создавать - они, соответственно, будут размещены в регистрах, если компилятор сможет их так распределить. если не сможет - то всё равно в сегменте данных. Сообщение отредактировал Iron Bug - 22.12.2011, 20:33 |
|
|
rp80 |
![]()
Сообщение
#19
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
смотря каких. константы могут быть сложены в сегмент кода (раз они не меняются). переменные, которые обычные - в сегменте данных. можно ещё регистровые переменные создавать - они, соответственно, будут размещены в регистрах, если компилятор сможет их так распределить. если не сможет - то всё равно в сегменте данных. Вообще вот цитата из википедии: A data segment is a portion of virtual address space of a program, which contains the global variables and static variables that are initialized by the programmer. Т.е. они называют сегментом данных то что вы называете сегментом кода. Непонятно кто прав.. А насчет утечек вот пример
Работает, не падает, разве это не говорит об утечке? Блок закрылся, переменная ar удалена из стека, но выделенный массив остался в памяти. И если я меняю размер массива на 10, то размер экзешника уменьшается (18693 на 18677). Т.е. похоже на то, что данные хранятся в коде. Но тогда получается что такой неявно заданный объект тоже хранит данные в сегменте кода. И везде где я читаю пишут что есть 3 типа памяти: Сегмент кода - хранит текст программы + константы и статик переменные. Стэк - хранит локальные переменные. Куча - хранит динамические переменные. Нигде не видел упоминание о сегменте данных как о 4ом виде памяти, связанном со стеком. Сообщение отредактировал rp80 - 22.12.2011, 23:25 |
|
|
Алексей1153 |
![]()
Сообщение
#20
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2944 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
rp80, стек то никуда не девается. А то, что ты правильно выводишь якобы - это уже мусор, одна ко по чистой случайности этот мусор пока ещё соответствует тому, что в него поместили внутри вложенного блока
попробуй вот так
Сообщение отредактировал Алексей1153 - 23.12.2011, 7:34 |
|
|
Iron Bug |
![]()
Сообщение
#21
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
Вообще вот цитата из википедии: A data segment is a portion of virtual address space of a program, which contains the global variables and static variables that are initialized by the programmer.Т.е. они называют сегментом данных то что вы называете сегментом кода. Непонятно кто прав.. ты дальше-то читай википедию. там в целом правильно написано. кусок константных данных в коде они там называют Rodata. а перезаписываемые данные, соответственно, сегментом данных. реализации распределения некоторых переменных в языках высокого уровня могут отличаться. какие-то компиляторы оптимизируют константы и помещают их в код, какие-то - нет, и оставляют их в сегменте данных. в любом случае есть основная разница: сегмент кода не доступен для записи, сегмент данных и стек - это всё, что меняется. если хочешь глубже понять принципы - читай про ассемблер. если тебя интересует конкретная реализация - ты можешь просто посмотреть адреса в отладчике, и сравнить с регистрами. в архитектуре PC сегмент кода - это то, куда указывает CS. стек - SS. а данные, как правило, помещаются либо в DS, либо в ES (но там могут быть и адреса других сегментов, если идёт обработка константных данных, например). однако, в дебажном варианте распределение немного другое, там есть ловушки для нулевых смещений и выхода за границы массивов, отсутствие оптимизации размещения и всяческие компиляторные вставки для отладки. там может быть немного другое распределение. Сообщение отредактировал Iron Bug - 23.12.2011, 7:47 |
|
|
BRE |
![]()
Сообщение
#22
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
если тебя интересует конкретная реализация - ты можешь просто посмотреть адреса в отладчике, и сравнить с регистрами. в архитектуре PC сегмент кода - это то, куда указывает CS. стек - SS. а данные, как правило, помещаются либо в DS, либо в ES (но там могут быть и адреса других сегментов, если идёт обработка константных данных, например). однако, в дебажном варианте распределение немного другое, там есть ловушки для нулевых смещений и выхода за границы массивов, отсутствие оптимизации размещения и всяческие компиляторные вставки для отладки. там может быть немного другое распределение. Это было актуально во времена ??-DOS работающей в реальном режиме. Сейчас большинство ОС работает в защищенном режиме (в сегментных регистрах храняться уже не адреса, а дескрипторы сегментов из специальных дескрипторных таблицах GDT или LDT), да и процессы все выполняются в flat-режиме, в котором все сегменты (код, данные, стек) настраиваются на одни и те жи адреса виртуальной памяти. Защита выполняется на уровне страниц памяти (защита на уровне сегментов не используется вообще - для скорости). Сообщение отредактировал BRE - 23.12.2011, 9:18 |
|
|
rp80 |
![]()
Сообщение
#23
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
rp80, стек то никуда не девается. А то, что ты правильно выводишь якобы - это уже мусор, одна ко по чистой случайности этот мусор пока ещё соответствует тому, что в него поместили внутри вложенного блока попробуй вот так
Ничего не меняется, какие переменные потом не определяй, все равно правильно работает ) |
|
|
Алексей1153 |
![]()
Сообщение
#24
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2944 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
rp80, значит компилятор разместил переменную не так, как я подумал ) Но это неважно, суть ты понял, я полагаю
|
|
|
Iron Bug |
![]()
Сообщение
#25
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Модератор Сообщений: 1611 Регистрация: 6.2.2009 Из: Yekaterinburg Пользователь №: 533 Спасибо сказали: 219 раз(а) Репутация: ![]() ![]() ![]() |
(в сегментных регистрах храняться уже не адреса, а дескрипторы сегментов из специальных дескрипторных таблицах GDT или LDT а, ну да. тут ещё оттуда придётся тащить данные. у дров есть функция взятия физического адреса, а вот в юзерспейсе я чота не помню, есть такая фича или нет... я-то живу в основном в кернеле ![]() в общем, тогда лучше не пытаться гадать, а взять какой-нить стандарт ELF или вендозные спецификации и почитать про конкретные оси и конкретные компиляторы. впрочем, от этого разницы никакой не будет. для программиста интерес представляет размер стека, оптимизация работы с указателями и решение использования стека или кучи. я в юзерских программах не парюсь и использую кучу. ибо она практически не ограничена и чаще всего скорость доступа совершенно не критична, так как юзерские программы обычно и без того тормозят из-за вывода и экономия на адресах не даёт никакого эффекта. |
|
|
BRE |
![]()
Сообщение
#26
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
|
|
|
rp80 |
![]()
Сообщение
#27
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
я в юзерских программах не парюсь и использую кучу. ибо она практически не ограничена и чаще всего скорость доступа совершенно не критична, так как юзерские программы обычно и без того тормозят из-за вывода и экономия на адресах не даёт никакого эффекта. Я бы тоже не стал лазить в такие дебри. Но стал тут разбираться с копированием объектов и вот такое поведение непонятно.
Выводит: 0 - 123 - Segmentation fault. Т.е. скопировался как надо только указатель на динамически выделенную память. Сообщение отредактировал rp80 - 23.12.2011, 10:41 |
|
|
Алексей1153 |
![]()
Сообщение
#28
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2944 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
rp80, как разберёшься с указателями на массивы, открой для себя std-контейнеры )
а в данном случае тебе нужно переопределить оператор присваивания (и конструктор по умолчанию) для корректного копирования |
|
|
rp80 |
![]()
Сообщение
#29
|
Студент ![]() Группа: Участник Сообщений: 36 Регистрация: 10.9.2011 Пользователь №: 2860 Спасибо сказали: 0 раз(а) Репутация: ![]() ![]() ![]() |
rp80, как разберёшься с указателями на массивы, открой для себя std-контейнеры ) а в данном случае тебе нужно переопределить оператор присваивания (и конструктор по умолчанию) для корректного копирования Так в том то и дело, что по идее копирование по умолчанию должно копировать почленно. И если мы потом поменяем значение по одному указателю, должно поменяться и второе |
|
|
BRE |
![]()
Сообщение
#30
|
![]() Профессионал ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 1112 Регистрация: 6.3.2009 Из: Ростов-на-Дону Пользователь №: 591 Спасибо сказали: 264 раз(а) Репутация: ![]() ![]() ![]() |
Т.е. скопировался как надо только указатель на динамически выделенную память. Кому надо? Компилятор сделал то что ты ему сказал. Сделал бинарную копию a2 равную a1 (потеряв при этом указатель на область памяти pi - утечка). Указатель a2.str как показывал "в никуда", так и показывает - отсюда вылет программы. Все ожидаемо. И если мы потом поменяем значение по одному указателю, должно поменяться и второе Так и есть. Там где ты меняешь что-то по указателю, там и меняется (a1.pi[ 0 ] и a2.pi[ 0 ] ). |
|
|
Алексей1153 |
![]()
Сообщение
#31
|
![]() фрилансер ![]() ![]() ![]() ![]() ![]() ![]() Группа: Участник Сообщений: 2944 Регистрация: 19.6.2010 Из: Обливион Пользователь №: 1822 Спасибо сказали: 215 раз(а) Репутация: ![]() ![]() ![]() |
rp80,
|
|
|
![]() ![]() ![]() |
![]() |
|
Текстовая версия | Сейчас: 12.7.2025, 7:11 |