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

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

Восстановить пароль Регистрация
 
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
25.05.2012, 22:13     Выделение памяти #1
Добрый вечер. Немогу никак понять некоторые тонкости выделения памяти.

Во первых: на что указывает указатель, при записи
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     Выделение памяти
Посмотрите здесь:

C++ Не выделение памяти
Выделение памяти C++
C++ Распределение памяти. Динамическое выделение памяти
Выделение памяти C++
Выделение памяти C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
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
 Аватар для 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
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
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
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
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
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
25.05.2012, 22:28  [ТС]     Выделение памяти #7
1. строка записывается в область памяти, а s присваивается адрес первого элемента.
а зачем же тогда нужен strdub, если без него все работает?
и разве char* s="abc"; и const char* s="abc"; компилируются по разному?
dr.curse
 Аватар для 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
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
25.05.2012, 22:31     Выделение памяти #9
Цитата Сообщение от h3mbr0 Посмотреть сообщение
и разве char* s="abc"; и const char* s="abc"; компилируются по разному?
Компилируются они одинаково, в том смысле, что код получится один и тот же. В первом случае GCC выдаст предупреждение.
Но вот при попытке записи через этот указатель в первом случае программа может "слететь" во время выполнения, а во втором случае компилятор ещё во время компиляции выдаст ошибку, что нельзя записывать по константному указателю.
h3mbr0
8 / 8 / 0
Регистрация: 12.03.2012
Сообщений: 125
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
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
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++
C++ выделение памяти
Выделение памяти(С = С++) C++

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

Или воспользуйтесь поиском по форуму:
grizlik78
Эксперт C++
 Аватар для grizlik78
1882 / 1414 / 101
Регистрация: 29.05.2011
Сообщений: 2,958
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     Выделение памяти
Ответ Создать тему
Опции темы

Текущее время: 01:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru