С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

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

Войти
Регистрация
Восстановить пароль
 
h3mbr0
248 / 91 / 21
Регистрация: 12.03.2012
Сообщений: 362
#1

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

25.05.2012, 22:13. Просмотров 957. Ответов 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[]? ведь он фактически не чем не отличается от обычной динамической переменной(или я чего то не знаю)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.05.2012, 22:13
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Выделение памяти (C++):

Распределение памяти. Динамическое выделение памяти - C++
an-1 an-2 ... a2

Выделение памяти, проверка на утечку памяти - C++
Интересуют два вопроса: 1. Правильно ли устроен алгоритм выделения, удаление и запись ячейки памяти? Может быть, есть более простые...

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

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

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

Выделение памяти - C++
В чём ошибка выделения памяти? Подскажите, друзья! #include "stdafx.h" #include "stdio.h" #include <iostream> #include...

13
antoha398
155 / 155 / 3
Регистрация: 29.03.2012
Сообщений: 418
25.05.2012, 22:20 #2
1. строка записывается в область памяти, а s присваивается адрес первого элемента.
2. первый вариант это с++ второй си.
3. это скорей зависит от задачи, и от работы некоторых стандартных функций
4. вроде как sizeof(s)/sizeof(*s)
1
dr.curse
389 / 345 / 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
1
grizlik78
Эксперт С++
1972 / 1465 / 122
Регистрация: 29.05.2011
Сообщений: 3,033
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;
В частных случаях есть способы, которые зависят от платформы (ОС/компилятор). В общем случае — никак. И в общем случае это не нужно, программист всегда имеет возможность сохранить в отдельной переменной размер выделенной памяти и передать его куда надо.
1
h3mbr0
248 / 91 / 21
Регистрация: 12.03.2012
Сообщений: 362
25.05.2012, 22:25  [ТС] #5
1. строка записывается в область памяти, а s присваивается адрес первого элемента.
а зачем же тогда нужен strdub, если без него все работает? и почему не получается например записать в указатель char* s; информацию, через скажем cin.getline(s,64);
0
antoha398
155 / 155 / 3
Регистрация: 29.03.2012
Сообщений: 418
25.05.2012, 22:25 #6
для указателей sizeof(s)=sizeof(*s), так что это не кактит, и насколько знаю узнать размер указателя невозможно
точно это для обычного массива
0
h3mbr0
248 / 91 / 21
Регистрация: 12.03.2012
Сообщений: 362
25.05.2012, 22:28  [ТС] #7
1. строка записывается в область памяти, а s присваивается адрес первого элемента.
а зачем же тогда нужен strdub, если без него все работает?
и разве char* s="abc"; и const char* s="abc"; компилируются по разному?
0
dr.curse
389 / 345 / 16
Регистрация: 11.10.2010
Сообщений: 1,907
25.05.2012, 22:28 #8
Цитата Сообщение от h3mbr0 Посмотреть сообщение
а зачем же тогда нужен strdub, если без него все работает? и почему не получается например записать в указатель char* s; информацию, через скажем cin.getline(s,64);
потому-что нужно сначала выделить память
0
grizlik78
Эксперт С++
1972 / 1465 / 122
Регистрация: 29.05.2011
Сообщений: 3,033
25.05.2012, 22:31 #9
Цитата Сообщение от h3mbr0 Посмотреть сообщение
и разве char* s="abc"; и const char* s="abc"; компилируются по разному?
Компилируются они одинаково, в том смысле, что код получится один и тот же. В первом случае GCC выдаст предупреждение.
Но вот при попытке записи через этот указатель в первом случае программа может "слететь" во время выполнения, а во втором случае компилятор ещё во время компиляции выдаст ошибку, что нельзя записывать по константному указателю.
1
h3mbr0
248 / 91 / 21
Регистрация: 12.03.2012
Сообщений: 362
25.05.2012, 22:34  [ТС] #10
ясно, то есть получается при объявлении strdup не нужен?
и как насчет моего последнего вопроса:
чем отличается new char[5]; от new char(5);? и почему динамический массив следует удалять через delete[]? ведь он фактически не чем не отличается от обычной динамической переменной(или я чего то не знаю)
0
antoha398
155 / 155 / 3
Регистрация: 29.03.2012
Сообщений: 418
25.05.2012, 22:39 #11
Цитата Сообщение от h3mbr0 Посмотреть сообщение
new char[5]
выделение памяти для 5 элементов.

Цитата Сообщение от h3mbr0 Посмотреть сообщение
new char(5);
вызов конструктора.
1
grizlik78
Эксперт С++
1972 / 1465 / 122
Регистрация: 29.05.2011
Сообщений: 3,033
25.05.2012, 22:41 #12
Цитата Сообщение от h3mbr0 Посмотреть сообщение
чем отличается new char[5]; от new char(5);?
В первом случае выделяется массив размером 5 элементов. Во втором случае создаётся переменная (объект) и инициализируется значением 5.
Цитата Сообщение от h3mbr0 Посмотреть сообщение
и почему динамический массив следует удалять через delete[]? ведь он фактически не чем не отличается от обычной динамической переменной(или я чего то не знаю)
При вызове delete вызывается деструктор для одной переменной, при вызове delete [] деструктор вызывается для каждого элемента массива.
Ну и в стандарте вызов delete для массива и вызов delete [] для отдельного объекта описывается как неопределённое поведение.
1
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 записать адрес хранения строки.
0
grizlik78
Эксперт С++
1972 / 1465 / 122
Регистрация: 29.05.2011
Сообщений: 3,033
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;
}
1
28.05.2012, 03:45
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.05.2012, 03:45
Привет! Вот еще темы с ответами:

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

Не выделение памяти - C++
По какой причине не работает это программа ? #include&lt;iostream&gt; #include &lt;string&gt; using namespace std; int main () ...

Выделение памяти(С = С++) - C++
Привет. Нужна помощь, в выделении памяти. Есть код на С, нужно перевести его в С++. int SaveFileOne(int i) { FILE *f; if ((f =...

Выделение памяти - C++
Здравствуйте! #include&lt;iostream&gt; int main() { int *mass = new int ; int *mass2 = new int ; std::cout &lt;&lt; (unsigned int)mass &lt;&lt;...


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

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

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