Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / указатели и строки в С++ / 25 сообщений из 27, страница 1 из 2
22.04.2014, 00:22
    #38620963
stud_nau
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
Добрый день.
Прошу меня простить если вопрос банален, но мне не удалось нагуглить четкий ответ, хоть эта тема и поднималась часто как в книгах так и на форумах.
Ниже я привожу свои рассуждения и хочу спросить правильны ли они:
Код: plaintext
1.
2.
3.
4.
	char *name;
	name = "BHGH";
	name = "ffffff";
	name = "sss";


программа резервирует три блока памяти и каждый блок содержит константы типа char(см. код выше);
каждый раз переменной name присваивается адрес первого байта нового выделенного блока;
вся память остается зарезервированной до конца выполнения программы;
этот код плохой, так как напрасно расходуется память (тем более если предположить что он вызывается где-то в цикле)

Если мои рассуждения верны, тогда возникает следующий вопрос:
Допустим есть класс MyString
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
class MyString
{
	char* chptr;
	int sizestr;

public:

	MyString();
	MyString(char*);
	~MyString();

	void operator=(char*);

	char* getStr();
	int getSize();
};

void MyString::operator=(char* charray)
{
	delete []chptr;
	for(sizestr =0;((int)charray[sizestr]) != 0; sizestr++);		
	chptr = new char[sizestr+1];
	for(int i = 0; i < sizestr; i++)
	{
		chptr[i]= charray[i];
	}
	chptr[sizestr] = 0;
};



Каждый раз когда я буду присваивать обьекту класса mystring значение литерала подобным образом (см.ниже) , память выделенная на строковой литерал будет оставаться зарезервированной до конца программы, то есть это будет не лучше чем первый кусок кода.
Код: plaintext
1.
2.
3.
	MyString str="string1";
	str = "string2";
        str = "string3";


Конечно для класса MyString можно определить разные удобные методы и операторы, но будет ли оправданным использование обьектов этого класса? Или же как делетнуть память на литерал, ведь может быть вариант когда присваивается значение переменной типа char[].
...
Рейтинг: 0 / 0
22.04.2014, 00:54
    #38620974
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
stud_nauпрограмма резервирует три блока памятиНет. Не программа.

stud_nauэтот код плохой, так как напрасно расходуется память (тем более если предположить что он вызывается где-то в цикле)Вывод не правильный по причине предыдущего "нет".
Остальные рассуждения верны.

stud_nauКаждый раз когда я буду присваивать обьекту класса mystring значение литерала подобным образом (см.ниже) , память выделенная на строковой литерал будет оставаться зарезервированной до конца программы, то есть это будет не лучше чем первый кусок кода. Нет. Это будет хуже. В первом коде ты перенаправляешь указатель. Во втором манипулирешь кучей.

stud_nauИли же как делетнуть память на литералНикак. Константы программе почти не подвластны.
Если ты не хочешь хранить подобные строки в тексте программы - подгружай их из файла по мере необходимости.
...
Рейтинг: 0 / 0
22.04.2014, 01:18
    #38620980
stud_nau
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
White Owl, спасибо за ответ!

White Owlstud_nauпрограмма резервирует три блока памяти

Нет. Не программа.

stud_nauэтот код плохой, так как напрасно расходуется память (тем более если предположить что он вызывается где-то в цикле)

Вывод не правильный по причине предыдущего "нет".
Остальные рассуждения верны.


объясните подробнее плиз, ..
память расходуется каждый раз на новый литерал , правильно?


White Owlstud_nauКаждый раз когда я буду присваивать обьекту класса mystring значение литерала подобным образом (см.ниже) , память выделенная на строковой литерал будет оставаться зарезервированной до конца программы, то есть это будет не лучше чем первый кусок кода.

Нет. Это будет хуже. В первом коде ты перенаправляешь указатель. Во втором манипулирешь кучей.


хуже потому что выделяю дополнительно память, в которую копирую литерал?
оправдано ли создание и использование такого класса если в нем много удобных методов и перегруженных операторов ?
А в стандартном классе (string.h) при присваивании типа x = "строка" , тоже память на литералы расходуется?
...
Рейтинг: 0 / 0
22.04.2014, 06:35
    #38621015
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
Компиляторы "хитрые" и не выделяют дважды память под одну и туже константную строку. Посмотри реальные адреса куда указывают твои указатели
Вот тест
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
void f1()
{
	char* a = "aaa";
	char* b = "bbb";
	printf("%s at %p\n", a, a);
	printf("%s at %p\n", b, b);
}

int main(){
	char* a = "aaa";
	char* b = "bbb";
	printf("%s at %p\n", a, a);
	printf("%s at %p\n", b, b);
	f1();
    return 0;
}



Результатaaa at 0041574C
bbb at 00415748
aaa at 0041574C
bbb at 00415748

Как видно из результата выделяется минимально необходимое количество памяти, поэтому нет смысла проводить самодельную оптимизацию.
...
Рейтинг: 0 / 0
22.04.2014, 07:45
    #38621035
White Owl
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
stud_nauобъясните подробнее плиз, ..
память расходуется каждый раз на новый литерал , правильно?Нет.
Нету никаких "новых" литералов.

Представь себе город с улицами. Я тебе даю бумажку с адресом. Ты идешь по этому адресу и что-то делаешь. Потом я тебе даю новую бумажку с адресом... Ты каждый раз при этом будешь строить новую улицу или пойдешь на существующую улицу?
Этот город - память компьютера, улицы - литералы, бумажка с адресом - указатель, а ты - программа.



stud_nauхуже потому что выделяю дополнительно память, в которую копирую литерал?Нет. Хуже потому что в первом случае ты просто записывал новый адрес в четырех-байтовую переменную - единственная атомарная операция. А во втором у тебя два цикла переменной длины плюс манипуляция кучей.

stud_nauоправдано ли создание и использование такого класса если в нем много удобных методов и перегруженных операторов ?Иногда да, иногда нет.

stud_nauА в стандартном классе (string.h) при присваивании типа x = "строка" , тоже память на литералы расходуется?string.h это вообще не класс.

Вообще, тебе сильно не стоит браться за C++ пока. Возьми простой Си и попытайся понять как он работает. После этого пойдешь в кресты.
...
Рейтинг: 0 / 0
22.04.2014, 11:05
    #38621208
smald
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
stud_nau
память расходуется каждый раз на новый литерал , правильно?


Когда делаете char* STR="We Will Rock You";
Компилятор, во время создания бинарника, пихает эту строку в сегмент данных
исполняемого файла, который при загрузке программы на исполнение, переносится в
сегмент данных программы в RAM.
А в стандартном классе (string.h) при присваивании типа x = "строка" , тоже память на литералы расходуется?

Если имели ввиду std::basic_string, то это не из string.h, копайте отсюда <string>.
И в случае с std::string, для размещения памяти под "строка" в конструкторе указатель
на память запрашивается у размещённого в std::string Allocator, который оформлен как структура в составе класса basic_string, и
который по умолчанию инициализируется классом std::allocator. Управление передаётся интерфейсной функци
аллокатора-allocate, которая возвращает указатель на область памяти и куда std::string переносит байты строки.
В std::allocator::allocate функция просто делает ::new, то есть запрашивает из кучи, и возвращает указатель.
...
Рейтинг: 0 / 0
22.04.2014, 14:41
    #38621598
stud_nau
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
Спасибо всем за ответы

но мне не все понятно, поэтому задам вопрос немного по другому.

Следующие строки :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
int main()
{
	char* chptr;

	chptr = "aaa";
	std::cout<<chptr<<"; chptr value - "<<(int*)chptr<<"\n";

	chptr = "aab";
	std::cout<<chptr<<"; chptr value - "<<(int*)chptr<<"\n";

	chptr = "aac";
	std::cout<<chptr<<"; chptr value - "<<(int*)chptr<<"\n";

	chptr = "aaa";
	std::cout<<chptr<<"; chptr value - "<<(int*)chptr<<"\n";

	std::cout<<std::endl;
	system("pause");
}



Дают такой результат:
Код: plaintext
1.
2.
3.
4.
aaa; chptr value - 012C7858
aab; chptr value - 012C783C
aac; chptr value - 012C7838
aaa; chptr value - 012C7858



Так вот, блоки памяти (012C783C,012C783C+1,012C783C+2,012C783C+3) и (012C7838,012C7838+1,012C7838+2,012C7838+3) доступны для других программ во время выполнения текущей программы?
...
Рейтинг: 0 / 0
22.04.2014, 15:11
    #38621658
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
stud_nauТак вот, блоки памяти (012C783C,012C783C+1,012C783C+2,012C783C+3) и (012C7838,012C7838+1,012C7838+2,012C7838+3) доступны для других программ во время выполнения текущей программы?
Почитай про устройство виртуальной памяти. Тут например
...
Рейтинг: 0 / 0
22.04.2014, 15:18
    #38621671
luislom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
stud_nauТак вот, блоки памяти (012C783C,012C783C+1,012C783C+2,012C783C+3) и (012C7838,012C7838+1,012C7838+2,012C7838+3) доступны для других программ во время выполнения текущей программы?

Для другого процесса, нет. Но можно оформить блок как IPC shared memory, тогда к нему
можно будет получать доступ с любого другого процесса.
...
Рейтинг: 0 / 0
22.04.2014, 15:24
    #38621688
stud_nau
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
Dima T,
почитал, но ответ на свой вопрос я там не нашел.
...
Рейтинг: 0 / 0
22.04.2014, 15:29
    #38621696
stud_nau
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
luislom,
то есть при таком присвоении литералов все таки расходуется память,...я понимаю что в данном случае это очень мало, но все таки
...
Рейтинг: 0 / 0
22.04.2014, 15:44
    #38621729
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
stud_nauDima T,
почитал, но ответ на свой вопрос я там не нашел.
Память выделяется страницами. По 4Кб если не ошибаюсь. Поэтому под твое виртуальное адресное пространство (012C783C и т.д) будет выделен кусок реальной памяти 4Кб и его ты будешь видеть по адресам 012C7000 ... 012C7FFF
Эти 4Кб будут недоступны другой программе, но если ты ими не будешь пользоваться (не будет обращений по этим адресам) и будет нехватка реальной памяти, то они просто освободятся (в общем случае уйдут в своп) и будут переданы другому процессу.

Почитай эту книгу там подробно и доступно расписано как виндовс память использует.
...
Рейтинг: 0 / 0
22.04.2014, 15:49
    #38621743
luislom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
stud_nauluislom,
то есть при таком присвоении литералов все таки расходуется память,...я понимаю что в данном случае это очень мало, но все таки

Конечно. Она расходуется на диске в секции данных бинарника, и
потом в RAM в сегменте данных процесса. Размеры strlen(literal)+1
...
Рейтинг: 0 / 0
22.04.2014, 16:01
    #38621774
stud_nau
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
Dima T,
спс, почитаю..

просто, на каждом шагу написано, "не забывайте удалять выделенную оператором new память ", а то что каждый строковой литерал занимает новый блок памяти не пишут..явно
...
Рейтинг: 0 / 0
22.04.2014, 16:09
    #38621792
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
stud_nauпросто, на каждом шагу написано, "не забывайте удалять выделенную оператором new память ", а то что каждый строковой литерал занимает новый блок памяти не пишут..явно
Так это совсем про другое, тут ты память не выделяешь и освобождать ее тебе не надо. Для констант подкачка в память идет из EXE.
Пишут потому что иногда и гигабайт надо выделить, а если забыть его освободить, то второй гигабайт может не выделиться, да и своп не резиновый (туда первый гигабайт ляжет и будет лежать пока твоя прога не завершится).
...
Рейтинг: 0 / 0
22.04.2014, 16:12
    #38621797
luislom
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
stud_nauDima T,
спс, почитаю..

просто, на каждом шагу написано, "не забывайте удалять выделенную оператором new память ", а то что каждый строковой литерал занимает новый блок памяти не пишут..явно

Литералами навыделяешь памяти ровно столько, сколько их сумеешь прописать в исходнике.
New зверь другой природы: представь, что в цикле с миллионом итераций будешь делать new на каждом без delete.
Память кончиться сразу.
...
Рейтинг: 0 / 0
22.04.2014, 16:17
    #38621812
stud_nau
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
ну что ж, точки над "i" расставлены, - всем спасибо...
можно закрывать наверно
...
Рейтинг: 0 / 0
22.04.2014, 17:30
    #38621944
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
On 22.04.2014 15:41, stud_nau wrote:

> Так вот, блоки памяти (012C783C,012C783C+1,012C783C+2,012C783C+3) и
> (012C7838,012C7838+1,012C7838+2,012C7838+3) доступны для других программ
> во время выполнения текущей программы?

Этот вопрос выходит за рамки языка С или С++.

Логической памяти -- нет, не доступны.
Физической памяти -- да, могут быть доступны.
Это всё для современных популярных ОС и естественно в других ОС это
может быть по-другому.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
22.04.2014, 17:30
    #38621945
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
On 22.04.2014 16:18, luislom wrote:

> Для другого процесса, нет.

Это достаточно наивное заявление.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
22.04.2014, 17:32
    #38621951
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
On 22.04.2014 17:01, stud_nau wrote:

> просто, на каждом шагу написано, "не забывайте удалять выделенную
> оператором new память ", а то что каждый строковой литерал занимает
> новый блок памяти не пишут..явно

ОК, ты её выделял ?
Оператором new выделял ?
Так о чём тогда разговор ?

Ты какие-то другие языки программирования знаешь ? (чтобы тебе пример
привести)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
22.04.2014, 17:35
    #38621959
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
stud_nauDima T,
спс, почитаю..

просто, на каждом шагу написано, "не забывайте удалять выделенную оператором new память ", а то что каждый строковой литерал занимает новый блок памяти не пишут..явно

Гм... Пишут, ещё как пишут.
Стандарт почитай.
...
Рейтинг: 0 / 0
22.04.2014, 18:26
    #38622029
smald
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
MasterZivЭто достаточно наивное заявление.


А не расскажет ли мастер в этом отдельно взятом государстве,
как я смогу получить данные из сегмента данных другого процесса?
Не зная его идентификаторов, и того, запущен он вообще или нет.
P.S работа происходит не в режиме ядра, а в режиме процесса пользовательского уровня.
...
Рейтинг: 0 / 0
22.04.2014, 18:31
    #38622037
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
MasterZiv,

к чему все это глумление? Все твои опусы выше можно коротко: "не умеешь писать - нех.. начинать".
...
Рейтинг: 0 / 0
22.04.2014, 18:55
    #38622072
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
smaldMasterZivЭто достаточно наивное заявление.


А не расскажет ли мастер в этом отдельно взятом государстве,
как я смогу получить данные из сегмента данных другого процесса?
Не зная его идентификаторов, и того, запущен он вообще или нет.
P.S работа происходит не в режиме ядра, а в режиме процесса пользовательского уровня.

Вопрос был не по получить, а про
"доступны ли для других программ
во время выполнения текущей программы".

Просто запусти несколько экземпляров такой программы — и сегмент констант почти наверняка у них будет один и он будет всем им доступен.
...
Рейтинг: 0 / 0
22.04.2014, 18:56
    #38622073
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
указатели и строки в С++
Dima TMasterZiv,

к чему все это глумление? Все твои опусы выше можно коротко: "не умеешь писать - нех.. начинать".

Где ты там узрел глумление, мой друг?
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / указатели и строки в С++ / 25 сообщений из 27, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]