Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
h3mbr0
210 / 53 / 12
Регистрация: 12.03.2012
Сообщений: 279
#1

Выделение памяти - C++

25.05.2012, 22:13. Просмотров 921. Ответов 13
Метки нет (Все метки)

Добрый вечер. Немогу никак понять некоторые тонкости выделения памяти.

Во первых: на что указывает указатель, при записи
C++
1
char* s="abc";
ведь здесь не используется strdup, а значит строка записывается в "никуда"? при этом если инициализировать как выше, все будет нормально, а если попытаться записать что либо в char* s; вылетит ошибка.

Во вторых: чем отличается к примеру
C++
1
char* s=new int;
от
C++
1
char* n=(char*)malloc(sizeof(char));
И в третьих: почему(для чего) используется и обычный массив (к примеру char buffer[256]) и динамическая память (char* str) скажем, в одном классе. Какая разница? и почему не используется что то одно?

Да, и вот еще: как узнать размер выделенной памяти? скажем для указателя
C++
1
char* s;
Добавлено через 8 минут
И еще: чем отличается new char[5]; от new char(5);? и почему динамический массив следует удалять через delete[]? ведь он фактически не чем не отличается от обычной динамической переменной(или я чего то не знаю)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.05.2012, 22:13     Выделение памяти
Посмотрите здесь:

Выделение памяти (new) - C++
Наткнулся на пример где делают непонятные мне выделения памяти с помощью new X* pi = new X; X* p2 = new X ; X* рЗ = new (&buffer )...

Выделение памяти - C++
int main() { FILE *fIn = NULL, *fOut =NULL; Error EMyError; CNodeStack *Start; CNodeStack *ListF = new CNodeStack; ...

Выделение памяти - C++
Нубский вопрос, но не могу до конца разобраться. Допустим, есть простое определение переменной: int ival = 1024; Когда и как...

Выделение памяти... - C++
Вот решил себе ликбез устроить и возникли вопросы: 1) Почему char* p = "fffff"; не реагирует на delete p 2) Когда надо...

Выделение памяти. - C++
Значит так.Задача такая. Ввести строки или строку символов. Сколько мы будем вводить символов неизвестно.Может быть 10 а может быть...

Выделение памяти - C++
Вот кусок кода, класс и функция добавления в список Класс занимает 64 бита, я добавляю 10 элементов в список - 640 бит Потом отнимаю...

Выделение памяти - C++
Доброго времени суток. Чтобы выделить память под двумерный массив в такой форме: //n - переменная, M - константа arr = new double...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
antoha398
155 / 155 / 3
Регистрация: 29.03.2012
Сообщений: 418
25.05.2012, 22:20     Выделение памяти #2
1. строка записывается в область памяти, а s присваивается адрес первого элемента.
2. первый вариант это с++ второй си.
3. это скорей зависит от задачи, и от работы некоторых стандартных функций
4. вроде как sizeof(s)/sizeof(*s)
dr.curse
386 / 342 / 16
Регистрация: 11.10.2010
Сообщений: 1,907
25.05.2012, 22:24     Выделение памяти #3
Цитата Сообщение от antoha398 Посмотреть сообщение
4. вроде как sizeof(s)/sizeof(*s)
для указателей sizeof(s)=sizeof(*s), так что это не кактит, и насколько знаю узнать размер указателя невозможно

Добавлено через 1 минуту
но если указатель на char то можно узнать с помощью strlen, или реализовать сомому strlen
grizlik78
Эксперт С++
1903 / 1435 / 109
Регистрация: 29.05.2011
Сообщений: 2,990
25.05.2012, 22:25     Выделение памяти #4
Цитата Сообщение от h3mbr0 Посмотреть сообщение
Во первых: на что указывает указатель, при записи
C++
1
char* s="abc";
Компилятор позаботится, чтобы строка "abc" оказалась размешена где-нибудь в доступной памяти. Но компилятор вправе разместить её в месте, доступном только для чтения, поэтому не только писать по этому указателю нельзя, но и само такое присваивание является устаревшим. Правильно записывать так:
C++
1
char const* s = "abc";
То есть указатель ссылается на константное, неизменяемое значение.
Цитата Сообщение от h3mbr0 Посмотреть сообщение
Во вторых: чем отличается к примеру
C++
1
char* s=new int;
от
C++
1
char* n=(char*)malloc(sizeof(char));
Первое есть только в C++, второе унаследовано из Си. Необходимость new вызвана тем, что при создании объектов должен быть автоматически вызван конструктор объекта. Для простых типов это не важно, хотя формальный конструктор есть и для них. Ну и области памяти для malloc и new используются разные.
Цитата Сообщение от h3mbr0 Посмотреть сообщение
И в третьих: почему(для чего) используется и обычный массив (к примеру char buffer[256]) и динамическая память (char* str) скажем, в одном классе. Какая разница? и почему не используется что то одно?
Статический массив имеет фиксированный размер и хранится внутри объекта. Динамический имеет переменный размер. Какой из массивов использовать зависит от того, что нужно получить. Не зная задачи трудно ответить.

Цитата Сообщение от h3mbr0 Посмотреть сообщение
Да, и вот еще: как узнать размер выделенной памяти? скажем для указателя
C++
1
char* s;
В частных случаях есть способы, которые зависят от платформы (ОС/компилятор). В общем случае — никак. И в общем случае это не нужно, программист всегда имеет возможность сохранить в отдельной переменной размер выделенной памяти и передать его куда надо.
h3mbr0
210 / 53 / 12
Регистрация: 12.03.2012
Сообщений: 279
25.05.2012, 22:25  [ТС]     Выделение памяти #5
1. строка записывается в область памяти, а s присваивается адрес первого элемента.
а зачем же тогда нужен strdub, если без него все работает? и почему не получается например записать в указатель char* s; информацию, через скажем cin.getline(s,64);
antoha398
155 / 155 / 3
Регистрация: 29.03.2012
Сообщений: 418
25.05.2012, 22:25     Выделение памяти #6
для указателей sizeof(s)=sizeof(*s), так что это не кактит, и насколько знаю узнать размер указателя невозможно
точно это для обычного массива
h3mbr0
210 / 53 / 12
Регистрация: 12.03.2012
Сообщений: 279
25.05.2012, 22:28  [ТС]     Выделение памяти #7
1. строка записывается в область памяти, а s присваивается адрес первого элемента.
а зачем же тогда нужен strdub, если без него все работает?
и разве char* s="abc"; и const char* s="abc"; компилируются по разному?
dr.curse
386 / 342 / 16
Регистрация: 11.10.2010
Сообщений: 1,907
25.05.2012, 22:28     Выделение памяти #8
Цитата Сообщение от h3mbr0 Посмотреть сообщение
а зачем же тогда нужен strdub, если без него все работает? и почему не получается например записать в указатель char* s; информацию, через скажем cin.getline(s,64);
потому-что нужно сначала выделить память
grizlik78
Эксперт С++
1903 / 1435 / 109
Регистрация: 29.05.2011
Сообщений: 2,990
25.05.2012, 22:31     Выделение памяти #9
Цитата Сообщение от h3mbr0 Посмотреть сообщение
и разве char* s="abc"; и const char* s="abc"; компилируются по разному?
Компилируются они одинаково, в том смысле, что код получится один и тот же. В первом случае GCC выдаст предупреждение.
Но вот при попытке записи через этот указатель в первом случае программа может "слететь" во время выполнения, а во втором случае компилятор ещё во время компиляции выдаст ошибку, что нельзя записывать по константному указателю.
h3mbr0
210 / 53 / 12
Регистрация: 12.03.2012
Сообщений: 279
25.05.2012, 22:34  [ТС]     Выделение памяти #10
ясно, то есть получается при объявлении strdup не нужен?
и как насчет моего последнего вопроса:
чем отличается new char[5]; от new char(5);? и почему динамический массив следует удалять через delete[]? ведь он фактически не чем не отличается от обычной динамической переменной(или я чего то не знаю)
antoha398
155 / 155 / 3
Регистрация: 29.03.2012
Сообщений: 418
25.05.2012, 22:39     Выделение памяти #11
Цитата Сообщение от h3mbr0 Посмотреть сообщение
new char[5]
выделение памяти для 5 элементов.

Цитата Сообщение от h3mbr0 Посмотреть сообщение
new char(5);
вызов конструктора.
grizlik78
Эксперт С++
1903 / 1435 / 109
Регистрация: 29.05.2011
Сообщений: 2,990
25.05.2012, 22:41     Выделение памяти #12
Цитата Сообщение от h3mbr0 Посмотреть сообщение
чем отличается new char[5]; от new char(5);?
В первом случае выделяется массив размером 5 элементов. Во втором случае создаётся переменная (объект) и инициализируется значением 5.
Цитата Сообщение от h3mbr0 Посмотреть сообщение
и почему динамический массив следует удалять через delete[]? ведь он фактически не чем не отличается от обычной динамической переменной(или я чего то не знаю)
При вызове delete вызывается деструктор для одной переменной, при вызове delete [] деструктор вызывается для каждого элемента массива.
Ну и в стандарте вызов delete для массива и вызов delete [] для отдельного объекта описывается как неопределённое поведение.
33parrots
3 / 3 / 0
Регистрация: 25.05.2012
Сообщений: 23
26.05.2012, 17:09     Выделение памяти #13
C++ (Qt)
1
 char* s="abc";
Но вот при попытке записи через этот указатель в первом случае программа может "слететь" во время выполнения
Вопрос от новичка - а каким образом тогда можно поменять указатель s чтобы он указывал на другую строку. Как я понял запись
C++ (Qt)
1
s="another";
недопустима, ведь в таком случае мы пытаемся перезаписать новую строку на место строки "abc". При записи
C++ (Qt)
1
s=&"another";
получаем ошибку
[C++ Error] try3.cpp(99): E2034 Cannot convert 'char ( *)[3]' to 'char *'
Неужели это значит что при первом описании у нас создаётся указатель на массив char'ов именно из 3 элементов.. Интуитивно кажется что указатель довольно универсальная вещь должна быть. Вообще странно, я вроде как пытаюсь в s записать адрес хранения строки.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.05.2012, 03:45     Выделение памяти
Еще ссылки по теме:

Выделение памяти - C++
Какая разница между выделением памяти функциями malloc, calloc, realloc и оператором new? И как изменить размер выделенной памяти без...

Выделение памяти - C++
Скажите пожалуйста что не так? Не могу получить доступ к элементу str = 12, stlb = 3 bool** tempValues = new(bool*); for(int i = 0;...

Выделение памяти - C++
Во время выполнения программы после ввода нескольких символов выводит ошибку: double free or corruption(out): 0x0000000001157010 ***...

выделение памяти - C++
Здравствуйте, помогите пожалуйста исправить ошибку, это лишь малая часть кода. В задании: поле name должно быть динамическим: char...

выделение памяти - C++
есть класс множество. необходимо создать класс "правило", одним из методов которого является добавление множества к соответствующему списку...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
grizlik78
Эксперт С++
1903 / 1435 / 109
Регистрация: 29.05.2011
Сообщений: 2,990
28.05.2012, 03:45     Выделение памяти #14
C++
1
2
3
4
char const* s = "abc";
std::cout << s << std::endl;
s = "another";
std::cout << s << std::endl;
Так менять указатель можно. Нельзя менять содержимое этих строк. Поэтому указатель объявляется как указатель на константу.

Добавлено через 6 минут
Цитата Сообщение от 33parrots Посмотреть сообщение
Неужели это значит что при первом описании у нас создаётся указатель на массив char'ов именно из 3 элементов.. Интуитивно кажется что указатель довольно универсальная вещь должна быть. Вообще странно, я вроде как пытаюсь в s записать адрес хранения строки.
Строковой литерал "something" является массивом символов. Он может быть преобразован в указатель на char автоматически (неявно). Так что задание строкового литерала в программе, по сути, и задаёт адрес этой строки. А вот указатель на массив char, это уже лишнее. Да и по типам он, как видно, не совместим с указателем на char.

Добавлено через 3 минуты
C++
1
2
3
4
5
6
7
8
#include <iostream>
 
int main()
{
    for (int i = 0; "something"[i] != '\0'; ++i)
        std::cout << "something"[i] << std::endl;
    return 0;
}
Yandex
Объявления
28.05.2012, 03:45     Выделение памяти
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru