Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> массв char*, выделение памяти 
V
    Опции темы
lv151
Дата 31.1.2009, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



char* arr[3] = {"str1", "str2", "str3"};
Почему во всех примерах, использования массива указателей на строки, память, для каждой, не выделяется оператором new?
Я ожидал что то вроде этого:
(Псевдокод)
Код

char* tmp_str = new char[4];
*tmp_str = "aaa";
arr[0] = tmp_str;






Это сообщение отредактировал(а) lv151 - 31.1.2009, 11:44
PM MAIL   Вверх
Avaj
Дата 31.1.2009, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 212
Регистрация: 14.7.2008
Где: Владивосток.

Репутация: 1
Всего: 3



Код

char* arr[3] = {"str1", "str2", "str3"};


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

Код

char *str = "aaa";
arr[0] = 'q';
 - нельзя, т.к. str - константная строка.

По-моему так.
PM MAIL   Вверх
lv151
Дата 31.1.2009, 12:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Это массив указателей на строки.
PM MAIL   Вверх
pan2004
Дата 31.1.2009, 12:25 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 357
Регистрация: 28.7.2007

Репутация: 2
Всего: 9



указатели не обязательно означают, что объект, на который они указывают, будет находится в heap.
В твоем примере создается массив указателей на стековую область памяти, поэтому никакого new.

Цитата(lv151 @  31.1.2009,  11:40 Найти цитируемый пост)
Я ожидал что то вроде этого:

так тоже можно, но надо не забыть потом сделать delete


--------------------
Qt4/C++ fan
WinXP SP3: MSVC++2005 Qt4.5.1 Boost1.39
сыграем в дурака?
PM MAIL   Вверх
Avaj
Дата 31.1.2009, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 212
Регистрация: 14.7.2008
Где: Владивосток.

Репутация: 1
Всего: 3



lv151,

Цитата

Это массив указателей на строки.
 - ну естественно что я это имел ввиду smile , и если уж на то пошло, то это массив указателей на первые символы строк.
PM MAIL   Вверх
lv151
Дата 31.1.2009, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



указатели не обязательно означают, что объект, на который они указывают, будет находится в heap.
В твоем примере создается массив указателей на стековую область памяти, поэтому никакого new

Это только для переменных символьного типа?

Это сообщение отредактировал(а) lv151 - 31.1.2009, 14:09
PM MAIL   Вверх
Christoph
Дата 31.1.2009, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 667
Регистрация: 23.1.2008
Где: Харьков

Репутация: нет
Всего: 11



Цитата(lv151 @ 31.1.2009,  12:17)
Это массив указателей на строки.

это указатель на область памяти, которая представлена как последовательность символов


--------------------
user posted image
PM MAIL ICQ   Вверх
lv151
Дата 31.1.2009, 18:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



ОК.
Почему char* arr[3] = {"str1", "str2", "str3"} - это прокатывает, а это -  int* i = 5 (или int* i;*i = 5;), нет.

Это сообщение отредактировал(а) lv151 - 31.1.2009, 18:13
PM MAIL   Вверх
mes
Дата 31.1.2009, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(lv151 @  31.1.2009,  17:11 Найти цитируемый пост)
или int* i;*i = 5;), нет.

почему нет ? это скомпилируется, просто в рантайме  вызовет ошибку записи не в свою память 
вот так правильней:
Код

 int j;
 int* i =&j;
*i = 5;


Цитата(lv151 @  31.1.2009,  17:11 Найти цитируемый пост)
 int* i = 5 нет.

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

  int* i = (int*)0xa000; 

ну а если нужен массив, то пишите так
Код

int i[] = {5,3,2};



Это сообщение отредактировал(а) mes - 31.1.2009, 18:53


--------------------
PM MAIL WWW   Вверх
lv151
Дата 31.1.2009, 18:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Цитата(mes @  31.1.2009,  18:49 Найти цитируемый пост)
почему нет ? это скомпилируется, просто в рантайме  вызовет ошибку записи не в свою память 

char* arr[3] = {"str1", "str2", "str3"}  - а почему это не вызывает?

PM MAIL   Вверх
mes
Дата 31.1.2009, 19:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(lv151 @  31.1.2009,  17:53 Найти цитируемый пост)
char* arr[3] = {"str1", "str2", "str3"}  - а почему это не вызывает?

потому что в Вашем сравнении Вы сравниваете разные вещи.
*i = 5; - запись в ячейку по разъименованому указателю.

Код

                                    //в правой части :
char  c[] = { 'a', 'b', 'c', '\0'}; // массив символов
int   i[] = {1,2,3};                // массив целочисленых значений

char * s = "abc";                   // строка , обратите внимание на отличие кавычек от первой строки.
char *sa[] = {"abc", "def", "ghi"}; // массив строк 




Это сообщение отредактировал(а) mes - 31.1.2009, 19:53


--------------------
PM MAIL WWW   Вверх
lv151
Дата 31.1.2009, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Да, я понимаю что char  c[]  - это адрес, т.е. указатель константа, char * s - указатель - переменная, но мы можем таким же образом работать и с int:

Код

int arr[5] = {1, 2, 3, 4, 5};

for (int j = 0; j < 5; j++)
{
 cout<<*(arr + j);
}


или

Код

int arr[5] = {1, 2, 3, 4, 5};
int* p_arr = arr;


for (int j = 0; j < 5; j++)
{
 cout<<*(p_arr++);
}


char* p = 'a'; - а это не запись в ячейку по разъименованому указателю?

так почему char* p = 'a', а так нет - int* p = 1; 

указатели не обязательно означают, что объект, на который они указывают, будет находится в heap.
В твоем примере создается массив указателей на стековую область памяти, поэтому никакого new


Почему для int* p = 1 не выделяется память в стеке, а на уровне компиляции:
error C2440: 'initializing' : cannot convert from 'int' to 'int *'    





Это сообщение отредактировал(а) lv151 - 31.1.2009, 20:52
PM MAIL   Вверх
mes
Дата 31.1.2009, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(lv151 @  31.1.2009,  19:50 Найти цитируемый пост)
так почему char* p = 'a', а так нет - int* p = 1; 

оба примера не будут компилироваться

Добавлено через 1 минуту и 18 секунд
Цитата(lv151 @  31.1.2009,  19:50 Найти цитируемый пост)
char* p = 'a'; - а это не запись в ячейку по разъименованому указателю?

это нет, а  
Код

 * p = 'a'; 
 -да

Добавлено через 11 минут и 28 секунд
Цитата(lv151 @  31.1.2009,  19:50 Найти цитируемый пост)
Да, я понимаю что char  c[]  - это адрес, т.е. указатель константа, char * s - указатель - переменная, но мы можем таким же образом работать и с int:

Вы путаетесь в уровнях, попробую зайти немного с другой стороны.

 вот Вам три однотипных инициализации массивов:
Код

char c[] = { 'a', 'b', 'c'}; 
char i [] = {1,2,3};           
string s[] = {"abc", "def", "ghi"}; 

все выглядит абсолютно одинаково- Вас устраивает ?
только для компилятора string это char * , поэтому третья строчка записывaется так :
Код

char *s[] = {"abc", "def", "ghi"}; 




--------------------
PM MAIL WWW   Вверх
lv151
Дата 31.1.2009, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



0) char *x = "asdq" - работает, char *x = {'a', 's', 'd', 'q'} - нет. Для удобства в компиляторе есть встроенный 
механизм работы со строками?
1) Т.Е. для компилятора char x[5] = "asdq" равно  char *x = "asdq"?, только во втором случае мы можем менять адрес переменной? 
2) Компилятор сам выделяет память? 
3) Как он получает адрес переменной? Это её адрес в "теле exe-ника"?




Это сообщение отредактировал(а) lv151 - 31.1.2009, 22:23
PM MAIL   Вверх
mes
Дата 31.1.2009, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(lv151 @  31.1.2009,  21:21 Найти цитируемый пост)
0) char *x = "asdq" - работает, char *x = {'a', 's', 'd', 'q'} - нет. Для удобства в компиляторе есть встроенный 
механизм работы со строками?

ага есть, правда примитивный, но польза большая.

Цитата(lv151 @  31.1.2009,  21:21 Найти цитируемый пост)
1) Т.Е. для компилятора char x[5] = "asdq" равно  char *x = "asdq"?, только во втором случае мы можем менять адрес переменной? 

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

Цитата(lv151 @  31.1.2009,  21:21 Найти цитируемый пост)
2) Компилятор сам выделяет память? 

char x[5] // компилятор создает на стеке массив из 5 элементов
         =  "asdq"; // и копирует в него эту строку
char *x = "asdq"; // тут ничего не выделяется в рантайме 
 
Цитата(lv151 @  31.1.2009,  21:21 Найти цитируемый пост)
) Как он получает адрес переменной? Это её адрес в "теле exe-ника"?

какой переменной ? адрес строки  ? грубо говоря да.




--------------------
PM MAIL WWW   Вверх
lv151
Дата 1.2.2009, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Цитата(mes @  31.1.2009,  22:57 Найти цитируемый пост)
char x[5] // компилятор создает на стеке массив из 5 элементов         =  "asdq"; // и копирует в него эту строку char *x = "asdq"; // тут ничего не выделяется в рантайме 


1) char *x = "asdq" – в данном случае значением указателя является адрес переменной в сегменте данных, который получаем во время компиляции? Правильно я понял?

2) А если переменная не глобальная?

fun()
{ 
   char x1[5]  = "aaaa";
   char *x = "asdq";
}

При вызове функции "aaaa" помещается в стек, после,  строка "asdq". Значением x является вершина стека?
т.е. стек выглядит так?

значение      адрес
asdq              04
aaaa              05

х = 04?


PM MAIL   Вверх
mes
Дата 1.2.2009, 13:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(lv151 @  1.2.2009,  09:41 Найти цитируемый пост)
1) char *x = "asdq" – в данном случае значением указателя является адрес переменной в сегменте данных, который получаем во время компиляции? Правильно я понял?

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

Цитата(lv151 @  1.2.2009,  09:41 Найти цитируемый пост)
При вызове функции "aaaa" помещается в стек, после,  строка "asdq". 

во время компиляции эти строки ложатся в сегмент данных, 
а в рантайме указатели инициализируются адресом  этой строки, а массивы данными той строки из сегмента данных.
Цитата(lv151 @  1.2.2009,  09:41 Найти цитируемый пост)
х = 04?

стек выглядит примерно так :

нач.адреес  значение      кон.адрес                      
00                 asdq\0           04 // x1[5] = 
05                 0x....              08  // где 0х... адрес строки
5 байт на массив, и 4 на указатель (для обычных (х86) 32хбитных машин, при условии отсутствия выравнивания на стеке.. но это смысла не меняет)


Это сообщение отредактировал(а) mes - 1.2.2009, 13:19


--------------------
PM MAIL WWW   Вверх
vinter
Дата 1.2.2009, 13:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(mes @  1.2.2009,  14:15 Найти цитируемый пост)
во время компиляции эти строки ложатся в сегмент данных,

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


--------------------
Мой блог
PM MAIL WWW   Вверх
mes
Дата 1.2.2009, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(vinter @  1.2.2009,  12:19 Найти цитируемый пост)
Во втором случе я вообще причн не вижу хранить строку, оставить ее в стеке и не марать сегмент данных вовсе. 

откуда она возьмется то в рантайме  ? )

Добавлено через 45 секунд
Цитата(vinter @  1.2.2009,  12:19 Найти цитируемый пост)
быть помещена в любой read only сегмент

это не принципиально и на текущий момент только запутает..



--------------------
PM MAIL WWW   Вверх
lv151
Дата 1.2.2009, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Посоветуйте, что можно почитать по данной теме.
PM MAIL   Вверх
vinter
Дата 1.2.2009, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(mes @  1.2.2009,  14:21 Найти цитируемый пост)
откуда она возьмется то в рантайме

а причем тут рантайм?
Цитата(lv151 @  1.2.2009,  11:41 Найти цитируемый пост)
char x1[5]  = "aaaa";

это не рантайм


--------------------
Мой блог
PM MAIL WWW   Вверх
GoldFinch
Дата 1.2.2009, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 6
Всего: 26



mes, хз как у С++ а в делфи константы кладутся в сегмент кода, сразу за телом функции в которой они используются
PM MAIL ICQ   Вверх
mes
Дата 1.2.2009, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(vinter @  1.2.2009,  13:22 Найти цитируемый пост)
а причем тут рантайм?
Код

char x1[5]  = "aaaa";

это не рантайм 

инициализация массива x1(заполнение стека) происходит  в рантайме.

Цитата(GoldFinch @  1.2.2009,  13:30 Найти цитируемый пост)
mes, хз как у С++ а в делфи константы кладутся в сегмент кода, сразу за телом функции в которой они используются 

также, зависит от компилятора и места  где определены данные (глобально или в функции)
в нашем случае сегмент данных, и данные в сегменте кода означает одно и то же, "данные хранящиеся в теле "ехешника" " и с точки зрения языка неразличимы.




Это сообщение отредактировал(а) mes - 1.2.2009, 14:43


--------------------
PM MAIL WWW   Вверх
lv151
Дата 1.2.2009, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Посоветуйте литературу по данной теме.

Это сообщение отредактировал(а) lv151 - 1.2.2009, 15:16
PM MAIL   Вверх
vinter
Дата 1.2.2009, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(mes @  1.2.2009,  15:35 Найти цитируемый пост)
инициализация массива x1(заполнение стека) происходит  в рантайме.

давай не будет понятия подменять, нет там никакого рантайма. Все известно на этапе компиляции.
Цитата(mes @  1.2.2009,  15:35 Найти цитируемый пост)
с точки зрения языка неразличимы.

с точик зрения языка вообще никаких сегментов нет, так, что ты изначально не прав.

Добавлено через 1 минуту и 1 секунду
Цитата(lv151 @  1.2.2009,  16:15 Найти цитируемый пост)
Посоветуйте, что можно почитать по данной теме.

книжки по С\С++ любые, огбсуждения книжек идут в прикрепленном топике


--------------------
Мой блог
PM MAIL WWW   Вверх
lv151
Дата 1.2.2009, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Цитата(vinter @  1.2.2009,  15:15 Найти цитируемый пост)
книжки по С\С++ любые, огбсуждения книжек идут в прикрепленном топике

Там так глубоко не копают. Просмотрел не одну, перед тем как задать вопрос.
PM MAIL   Вверх
vinter
Дата 1.2.2009, 15:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(lv151 @  1.2.2009,  16:24 Найти цитируемый пост)
Там так глубоко не копают. Просмотрел не одну, перед тем как задать вопрос.

потомучто это копание отношения к С++ не имеет, это уже зависит от реализации. Самая подробная книга у Страуструпа, знать глубже чем там написано, зачастую даже вредно smile


--------------------
Мой блог
PM MAIL WWW   Вверх
mes
Дата 1.2.2009, 16:21 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(vinter @  1.2.2009,  14:15 Найти цитируемый пост)
давай не будет понятия подменять, нет там никакого рантайма. Все известно на этапе компиляции.

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

Цитата(vinter @  1.2.2009,  14:15 Найти цитируемый пост)
с точик зрения языка вообще никаких сегментов нет, так, что ты изначально не прав.

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

Цитата(mes @  31.1.2009,  21:57 Найти цитируемый пост)
Это её адрес в "теле exe-ника"

Цитата(mes @  31.1.2009,  21:57 Найти цитируемый пост)
грубо говоря да.


Цитата(mes @  1.2.2009,  12:21 Найти цитируемый пост)
это не принципиально и на текущий момент только запутает

не вид, ни место хранения данных, которыми заполняется массив не важен. 

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



--------------------
PM MAIL WWW   Вверх
vinter
Дата 1.2.2009, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(mes @  1.2.2009,  17:21 Найти цитируемый пост)
и так когда происходит создание и инициализация массива ?

в рантайме, но для языка это рантаймом не является потому, как не зависит ни от каких внешних факторов и всегда статично.


--------------------
Мой блог
PM MAIL WWW   Вверх
mes
Дата 1.2.2009, 16:29 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(vinter @  1.2.2009,  15:26 Найти цитируемый пост)
в рантайме, но для языка это рантаймом не является потому, как не зависит ни от каких внешних факторов и всегда статично. 

т.е инициализация стека происходит в рантайме, но рантаймом не является.. так ? интересно..
так  данные в стек помещаются на этапе компиляции ? если нет , то откуда берутся ?
или я неправильно трактую Ваше высказывание  ? :
Цитата(vinter @  1.2.2009,  12:19 Найти цитируемый пост)
Во втором случе я вообще причн не вижу хранить строку, оставить ее в стеке и не марать сегмент данных вовсе. 



Это сообщение отредактировал(а) mes - 1.2.2009, 16:38


--------------------
PM MAIL WWW   Вверх
vinter
Дата 1.2.2009, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 8
Всего: 56



Цитата(mes @  1.2.2009,  17:29 Найти цитируемый пост)
т.е инициализация стека происходит в рантайме, но рантаймом не является.. так ?

именно так, не надо путать языковый рантайм с реальным. Я еще раз повторяю, для языка это не является рантаймом. Для языка рантаймом является: выделение памяти, исключения и т.д. Но уж точно не стек.
 
Цитата(mes @  1.2.2009,  17:29 Найти цитируемый пост)
Во втором случе я вообще причн не вижу хранить строку, оставить ее в стеке и не марать сегмент данных вовсе. 

ступил. Строку хранить надо.


--------------------
Мой блог
PM MAIL WWW   Вверх
mes
Дата 1.2.2009, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(vinter @  1.2.2009,  16:40 Найти цитируемый пост)
Я еще раз повторяю, для языка это не является рантаймом. Для языка рантаймом является: выделение памяти, исключения и т.д. Но уж точно не стек.

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




--------------------
PM MAIL WWW   Вверх
lv151
Дата 1.2.2009, 18:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Цитата(vinter @  1.2.2009,  15:33 Найти цитируемый пост)
потомучто это копание отношения к С++ не имеет, это уже зависит от реализации. Самая подробная книга у Страуструпа, знать глубже чем там написано, зачастую даже вредно

Да вот в данный момент его и читал smile
Всё равно хочу разобраться.
PM MAIL   Вверх
Arden
Дата 3.2.2009, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.1.2009
Где: Украина, Волынь

Репутация: нет
Всего: нет



Показалась тема похожей, поэтому новой создавать не стал. Есть вот такой код:
Код

#include <cstdlib>
#include <iostream>
#include <string.h>

using namespace std;

int main(int argc, char *argv[])
{
    char a[5][20];
    for(int i=0; i<5; i++){
            cin>>*(a+i);
            }
    char *p;
    int n;
    for(int i=0; i<4; i++){
            for(int j=0; j<4-i; j++){
                    n = strcmp(*(a+j), *(a+j+1));
                    if(n>0){
                            strcpy(p, *(a+j));
                            strcpy(*(a+j), *(a+j+1));
                            strcpy(*(a+j+1), p);
                            }
                    }
            }
    cout<<endl;
    for(int i=0; i<5; i++){
            cout<<*(a+i)<<endl;
            }
    system("PAUSE");
    return EXIT_SUCCESS;
}


Программа компилируется и запускается нормально. Инициализирую массив и когда входит в цикл, программа выдает ошибку с текстом:
Код

Инструкция по адресу "0х77с360с1" обратилась к памяти по адресу "0х00000005". Память не может быть "written".

Если использовать в цикле вместо указателя char *p массив char p[20], то программа работает. Возникло несколько вопросов:

1) Почему тогда например код 
Код

char *p, A[20], B[20];
cin>>A;
cin>>B;
strcpy(p, A);
strcpy(A, B);
strcpy(B, p);

работает, а практически такой же код в цикле - нет?

2) Часто встречаю примеры типа:
Код

char a[] = "Univercity";
char *p;
p = strcat(a, "blabla");

Это вообще нормально? Куда указывает указатель *p до момента его инициализации?

3) В чём разница между строчками
Код

char a[] = "University";

и
Код

char *p = "University";

Я так понимаю, что а всегда указывает на 1 элемент массива, а p можно сместить, например с помощью инкремента. Я правильно понял? А в чём еще разница? 
Надеюсь я нормально выразился. Только недавно начал учить программирование, дошел до строчек и тут немножко запутаться.

Это сообщение отредактировал(а) Arden - 3.2.2009, 20:06
PM MAIL   Вверх
pan2004
Дата 3.2.2009, 20:24 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 357
Регистрация: 28.7.2007

Репутация: 2
Всего: 9



Arden, вообще код имхо ужасный изза подобных операций над двумерным массивом. Не стал разбираться, потому что думаю, ты там что-то напутал. например, если a массив типа char[5][20], то куда будет указывать a+1? Явно не туда, куда ты думаешь) Не путай здесь массивы с указателями, разные это вещи.
1) Сомневаюсь, что даже этот код работает - p указывает в пустоту.
2) Это нормально. Пофиг, куда указывает p до вызова strcat - он инициализируется этой функцией. (если интересно, до этого он указывает на случайный адрес, но здесь это ни на что не влияет)
3) 
Цитата(Arden @  3.2.2009,  20:04 Найти цитируемый пост)
char *p = "University";

вот так советуют ни в коем случае не делать! Может создаться впечатление, что это указатель на неконстантную строку, но, увы, это не так. При попытке изменить ее будет UB(программа вылетит скорее всего). Если уж так, то пиши const char*.

Цитата(Arden @  3.2.2009,  20:04 Найти цитируемый пост)
char a[] = "University";

более-менее аналогично 
Код

const char* ta="University";
char a[N];
strcpy(a, ta);



--------------------
Qt4/C++ fan
WinXP SP3: MSVC++2005 Qt4.5.1 Boost1.39
сыграем в дурака?
PM MAIL   Вверх
mes
Дата 3.2.2009, 21:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Arden @  3.2.2009,  19:04 Найти цитируемый пост)
Это вообще нормально? Куда указывает указатель *p до момента его инициализации?

куда ему вздумается, поэтому такой указатель невалидный. Перед началом работы с ним, проиницилизируйте указатель адресом области памяти с которой будете взаимодействовать.



--------------------
PM MAIL WWW   Вверх
Arden
Дата 4.2.2009, 00:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.1.2009
Где: Украина, Волынь

Репутация: нет
Всего: нет



Цитата(pan2004 @  3.2.2009,  19:24 Найти цитируемый пост)
Не стал разбираться, потому что думаю, ты там что-то напутал.

Да вроде как не напутал. Программа должна 5 введенных строк упорядочить по алфавиту. Алгоритм практически такой же, как при сортировке пузырьком. Для сравнения двух стрингов использую функцию strcmp(a, b). Если a>b, то меняю их местами.

Цитата(pan2004 @  3.2.2009,  19:24 Найти цитируемый пост)
например, если a массив типа char[5][20], то куда будет указывать a+1?

a+1 будет указывать на начало второй строчки, тоесть на элемент a[1][0].

Цитата(pan2004 @  3.2.2009,  19:24 Найти цитируемый пост)
1) Сомневаюсь, что даже этот код работает - p указывает в пустоту.

Работает. Я бы не рвался сразу на форум, не помучив голову самому себе сначала smile  Если для p выделить память с помощью new, то всё прекрасно работает. Но вот мне интересно стало почему тогда вне цикла работает и без инициализации указателя smile 

Цитата(mes @  3.2.2009,  20:44 Найти цитируемый пост)
куда ему вздумается, поэтому такой указатель невалидный. Перед началом работы с ним, проиницилизируйте указатель адресом области памяти с которой будете взаимодействовать.

Тоесть с "пустыми" указателями желательно не работать? Именно это меня и смутило, в книге нашел полно таких примеров smile 
PM MAIL   Вверх
mes
Дата 4.2.2009, 01:03 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(Arden @  3.2.2009,  23:55 Найти цитируемый пост)
Тоесть с "пустыми" указателями желательно не работать? Именно это меня и смутило, в книге нашел полно таких примеров smile  

 желательно не работать?  smile  smile 
С неинициализированными указателями НЕЛЬЗЯ работать.

Цитата(Arden @  3.2.2009,  23:55 Найти цитируемый пост)
a+1 будет указывать на начало второй строчки, тоесть на элемент a[1][0].

а не второго столбца  ?

Цитата(Arden @  3.2.2009,  23:55 Найти цитируемый пост)
Работает. 

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



Это сообщение отредактировал(а) mes - 4.2.2009, 15:19


--------------------
PM MAIL WWW   Вверх
Arden
Дата 4.2.2009, 01:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.1.2009
Где: Украина, Волынь

Репутация: нет
Всего: нет



Цитата(mes @  4.2.2009,  00:03 Найти цитируемый пост)
 желательно не работать?     С неициализированными указателями НЕЛЬЗЯ работать.

"Намек" понял smile 

Цитата(mes @  4.2.2009,  00:03 Найти цитируемый пост)
а не второго столбца  ?

Именно. Спасибо, что поправили.
PM MAIL   Вверх
Arden
Дата 4.2.2009, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.1.2009
Где: Украина, Волынь

Репутация: нет
Всего: нет



А как вывести адрес области, на которую указывает указатель типа char? Ведь при
Код

cout<<*p;

и
Код

cout<<p;

мы получим символ и строку соответственно, а как получить сам адрес так как при других типах?
PM MAIL   Вверх
MAKCim
Дата 4.2.2009, 14:49 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 2
Всего: 207



Цитата(Arden @  4.2.2009,  14:20 Найти цитируемый пост)
мы получим символ и строку соответственно, а как получить сам адрес так как при других типах? 

Код

cout<<(void*)p;



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Arden
Дата 4.2.2009, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 23.1.2009
Где: Украина, Волынь

Репутация: нет
Всего: нет



MAKCim,
спасибо.
PM MAIL   Вверх
lv151
Дата 8.2.2009, 11:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Нашёл ответ одним предложением:
Компилятор неявно выполняет преобразование const_char из const char[N] в char*(char* str = "String").

Это сообщение отредактировал(а) lv151 - 8.2.2009, 11:25
PM MAIL   Вверх
pan2004
Дата 8.2.2009, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 357
Регистрация: 28.7.2007

Репутация: 2
Всего: 9



lv151, лучше бы он этого не делал. Избавление от const обычно требует const_cast<>.
Хотя, gcc дает предупреждение:
Цитата

temp.cpp: In function ‘int main()’:
temp.cpp:35: warning: deprecated conversion from string constant to ‘char*’



--------------------
Qt4/C++ fan
WinXP SP3: MSVC++2005 Qt4.5.1 Boost1.39
сыграем в дурака?
PM MAIL   Вверх
lv151
Дата 8.2.2009, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 916
Регистрация: 11.2.2008

Репутация: нет
Всего: 2



Это С++, в С другой механизм. Наверно, тоже основан на приведении типов. 
PM MAIL   Вверх
Страницы: (3) [Все] 1 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1102 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.