(ссылка внизу) Я правильно понял что имя массива после инициализации указывает только на адрес в стеке, а сам массив с данными находится в куче?
Например: arr[15]; Теперь имя массива arr будет содержать адрес в стеке и указывать на адрес в куче?
Соответственно самому адресу в стеке ничего присвоить нельзя, нужно использовать обходные пути?
Действие показанное по ссылке можно легко совершить с обыкновенными переменными, но не получается совершить с массивом. Пытаюсь разобраться почему такая дискриминация.
https://coderoad.ru/14915924/Присвоение-значения-массиву-char
13 ое сообщение.
Не по теме:
Кстати отличное видео про стек и кучу https://www.youtube.com/watch?v=Fw30RClNoas
C/C++
Имя массива после инициализации принимает адрес в стеке, который указывает на адрес в куче? (Си)
В куче выделяется память, если объект создан динамически - через new или malloc.
На стеке - если статически (char arr[15] ;)
Массив всегда указывает на 0й элемент.
Т. е.
*arr == arr[0];
*(arr + 1) == arr[ 1 ];
chat arr[15];
arr = "Hi";
не работает, т. к. это разные типы данных:
arr - это char[15]
"Hi" - это const char[3];
char* arr = new char[15];
arr = "Hi";
работает, но не копирует.
Разбираем по строчкам:
1) char* arr = new char[15];
Выделили память из кучи на 15 байт, указатель на начало выложенного куска положили в arr
2) arr = "Hi";
На стеке выделили 3 байта, положили в них 3 символа, указатель на начало положили в arr. В итоге выделенные 15 байт из кучи потеряли, т. к. теперь на них никто не указывает - memory leak.
На стеке - если статически (char arr[15] ;)
Массив всегда указывает на 0й элемент.
Т. е.
*arr == arr[0];
*(arr + 1) == arr[ 1 ];
chat arr[15];
arr = "Hi";
не работает, т. к. это разные типы данных:
arr - это char[15]
"Hi" - это const char[3];
char* arr = new char[15];
arr = "Hi";
работает, но не копирует.
Разбираем по строчкам:
1) char* arr = new char[15];
Выделили память из кучи на 15 байт, указатель на начало выложенного куска положили в arr
2) arr = "Hi";
На стеке выделили 3 байта, положили в них 3 символа, указатель на начало положили в arr. В итоге выделенные 15 байт из кучи потеряли, т. к. теперь на них никто не указывает - memory leak.
char arr[15] ; - массив в стэке данных
char *arr =(char*) malloc(15*sizeof(char)); - массив в куче (ОЗУ), или вектор
char *arr =(char*) malloc(15*sizeof(char)); - массив в куче (ОЗУ), или вектор
Шодмон Ибрагимов
Можно как нибудь самому узнать что где находится? В стеке или в куче. Может с помощью IDE?
У меня есть Code Block и Qt Creator.
У меня есть Code Block и Qt Creator.
Шодмон Ибрагимов
Я имел в виду может можно обратиться к переменной: Ты где находишься? И она ответила бы: В стеке, либо в куче.
Шодмон Ибрагимов
Судя по этому видео https://www.youtube.com/watch?v=Fw30RClNoas
char *arr. В arr находится адрес, который содержится в Стеке. Адрес в Стеке, который указывает на адрес в Куче.
*arr Эта штука уже ссылается на значение, по адресу в куче.
char *arr. В arr находится адрес, который содержится в Стеке. Адрес в Стеке, который указывает на адрес в Куче.
*arr Эта штука уже ссылается на значение, по адресу в куче.
Шодмон Ибрагимов
Если это правда, то нельзя однозначно сказать находится ли это arr [ ] в Стеке или в Куче.
Указатель в Стеке, а Значение в Куче.
Указатель в Стеке, а Значение в Куче.
Шодмон Ибрагимов
Матрица? Да, смотрел. Там в конце Нео через стены летает.
Шодмон Ибрагимов
Посмотрел про матрицы. Это двумерные массивы.
Ещё непонятно с простейшими вещами, зачем мне пока что двумерные массивы.
Ещё непонятно с простейшими вещами, зачем мне пока что двумерные массивы.
Шодмон Ибрагимов
Не выгорю. Просто хочу разобраться во всём. Потом идёт намного легче всё. Например когда узнал что имя массива это указатель, сразу стало понятно почему ему нельзя присвоить что нибудь обычным способом. А то ведь мучался, приходилось принимать на веру некоторое и печатать код не понимая смысл.
Шодмон Ибрагимов
В принципе видео, которое я дал замечательное и по нему всё понятно где что находится, я это описал тоже. Но тут перешли на двумерные массивы и матрицы. Об этом я ещё не думал. А объясняете вы сложно иногда.
Я думаю что только имя (Адрес) двумерного массива находится в стеке. Значения двумерного массива находятся в куче.
То есть arr[ 6] [5]. Адрес arr, указывающий на кучу находится в Стеке, А сама матрица массива находится в куче arr[ 6] [5]
Источник информации пока что у меня: Интернет. Поднаберусь немного знаний и начну читать книгу. Не выбрал точно какую ещё.
Я думаю что только имя (Адрес) двумерного массива находится в стеке. Значения двумерного массива находятся в куче.
То есть arr[ 6] [5]. Адрес arr, указывающий на кучу находится в Стеке, А сама матрица массива находится в куче arr[ 6] [5]
Источник информации пока что у меня: Интернет. Поднаберусь немного знаний и начну читать книгу. Не выбрал точно какую ещё.
Шодмон Ибрагимов
Или может быть что все Адреса на значения двумерного массива находятся в Стеке. arr[6 ] [5]
На это свой указатель из стека [6] И на это свои указатель, который находится в стеке [5]
На это свой указатель из стека [6] И на это свои указатель, который находится в стеке [5]
Шодмон Ибрагимов
Немного с другой стороны посмотрим на это.
Если существует переменная arr двумя звёздочками **, значит за ней скрываются два адреса.
В данном случае представим что arr это двумерный массив и невидимыми для нас остаются адреса переменных b и а.
#include
int main(){
int a =5;
int *b = &a;
int **arr =&b;
printf("%p\n%p\n", *arr, arr);
}
В итоге получаем два разных адреса. Адрес переменной b и адрес переменной а.
-----------------------
Теперь "аналог" кода выше, но с двумерным массивом
#include
int main(){
int arr[2][10];
printf("%p\n%p\n", *arr, arr);
}
Получаем один адрес. Получается все адреса массива, указывающие на кучу находящиеся в стеке имеют один адрес.
Если существует переменная arr двумя звёздочками **, значит за ней скрываются два адреса.
В данном случае представим что arr это двумерный массив и невидимыми для нас остаются адреса переменных b и а.
#include
int main(){
int a =5;
int *b = &a;
int **arr =&b;
printf("%p\n%p\n", *arr, arr);
}
В итоге получаем два разных адреса. Адрес переменной b и адрес переменной а.
-----------------------
Теперь "аналог" кода выше, но с двумерным массивом
#include
int main(){
int arr[2][10];
printf("%p\n%p\n", *arr, arr);
}
Получаем один адрес. Получается все адреса массива, указывающие на кучу находящиеся в стеке имеют один адрес.
Шодмон Ибрагимов
Знаю точно что если б был инструмент работы со стеком, кучей, то я сам бы во всём разобрался эксперементальным путём. Так хоть 10 книг прочитай, без практики бесполезно. Я из пары книг уже читал главы по указателям.
Нужен инструмент, дебаггер, комманды показывающие где что находится и. т. п. не знаю что делать.
Остальное всё идёт довольно легко, зацикливаюсь я только на том что нельзя увидеть, проверить. Этот блин указатель.
В целом всё понятно, но мне надо "пощупать" его.
Нужен инструмент, дебаггер, комманды показывающие где что находится и. т. п. не знаю что делать.
Остальное всё идёт довольно легко, зацикливаюсь я только на том что нельзя увидеть, проверить. Этот блин указатель.
В целом всё понятно, но мне надо "пощупать" его.
Такой массив располагается на стеке. Имя массива - указатель на первый элемент этого массива, и указатель этот также лежит на стеке.
Конструкция
char arr[15] = {45};
считай то же, что и (формально - это не то же самое!):
char * const arr = (char [15]) {45}; - все данные лежат на стеке.
Конструкция
char arr[15] = {45};
считай то же, что и (формально - это не то же самое!):
char * const arr = (char [15]) {45}; - все данные лежат на стеке.
Анар Аскеров
"Действие показанное по ссылке можно легко совершить с обыкновенными переменными, но не получается совершить с массивом. Пытаюсь разобраться почему такая дискриминация."
Как я показал выше, имя массива - это константный указатель. То есть переменная, значение которой изменять нельзя. Кроме того, не стоит путать записи:
const char *ptr; - указатель на const char. Значение указателя менять можно, а вот значение, которое лежит по этому указателю - нельзя.
char const * ptr; или char * const ptr; - одно и то же. Здесь же можно менять значение, лежащее по указателю, а вот сам указатель менять нельзя.
const char const *ptr; - нельзя менять ни указатель, ни значение, лежащее по указателю.
Как я показал выше, имя массива - это константный указатель. То есть переменная, значение которой изменять нельзя. Кроме того, не стоит путать записи:
const char *ptr; - указатель на const char. Значение указателя менять можно, а вот значение, которое лежит по этому указателю - нельзя.
char const * ptr; или char * const ptr; - одно и то же. Здесь же можно менять значение, лежащее по указателю, а вот сам указатель менять нельзя.
const char const *ptr; - нельзя менять ни указатель, ни значение, лежащее по указателю.
Имя массива является указателем на первый элемент массива. Массив это не куча, а непрерывная область памяти.
Макс Бобохоликов
Куча - область памяти
Шодмон Ибрагимов
Я говорил о понятиях стека и кучи (heap)
Вы так поняли да?
Указатель значит не всегда указывает на адрес в куче?
Вы так поняли да?
Указатель значит не всегда указывает на адрес в куче?
Шодмон Ибрагимов
Значит указатель можно воспринимать как массив, в нулевом массиве которого находится значение этого указателя?
Я проверил это кодом:
#include
int main(){
int a =5;
int *ukazatel = &a;
printf("%d\n", ukazatel[0]);
}
Я проверил это кодом:
#include
int main(){
int a =5;
int *ukazatel = &a;
printf("%d\n", ukazatel[0]);
}
Шодмон Ибрагимов
*в нулевом элементе которого
Похожие вопросы
- С++, как оставить без изменений данные в char* который указывает на внутренний буфер вектора?
- Рекурс.функцию, которая принимает 2х-мерный массив целых чисел и кол-во сдвигов и выполняет круговой сдвиг массива влево
- Написать РЕКУРСИВНУЮ функцию, которая принимает двухмерный массив целых чисел и выполняет круговой сдвиг массива ВЛЕВО.
- Напишите рекурсивную функцию, которая принимает двухмерный массив целых чисел и количество сдвигов и выполняет
- C++: где vector хранит внутренний массив? В стеке или в куче?
- Упорядочить элементы массива по возрастанию на языке Си
- Помогите добавить ввод чисел в массив матрицы на языке Си
- Как обработать этот массив на языке Си?
- Constexpr инициализация статических массивов.
- Как в функции распечатать двумерный динамический массив в Си
https://ravesli.com/urok-105-stek-i-kucha/
Комманды, или может напрямую посмотреть может где что лежит в реальном времени.