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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Инициализация указателей, переданных в параметрах, запутался 
:(
    Опции темы
INHazeR
Дата 21.5.2007, 00:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



имеется некая функция
Код

void Foo(char* s, int* p)
{
    //code
}

Необходимо, чтобы после выполнения данной функции по адресу s находилась некая строка (массив char), а по адресу p - массив целых чисел.

В случае с целыми числами сделал просто
Код

*(p) = 5;
*(++p) = 2;
*(++p) = 4;

т.к. было известно, что возвращаемый массив всегда из 3-х чисел. При этом, приходится создавать этот массив вне функции, до ее вызова.
В случае с массивом чаров, даже при предварительном создании массивов соответствующей длины, вызов внутри Foo функций itoa ведет к ошибкам... вроде бы как память не выделена.
В общем, как по этим указателям корректно создать и заполнить соотвествующие массивы?
Заранее спасибо.
PM MAIL   Вверх
zkv
Дата 21.5.2007, 00:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(INHazeR @  21.5.2007,  00:45 Найти цитируемый пост)
В случае с массивом чаров, даже при предварительном создании массивов соответствующей длины, вызов внутри Foo функций itoa ведет к ошибкам... вроде бы как память не выделена.

вероятно проблема в нуль-символе, выделяйте память на 1 больше чем фактически требуется, в конец добавляйте нуль-символ ('\0' или просто 0), по нему функции определяют конец строки.
PM MAIL   Вверх
INHazeR
Дата 21.5.2007, 00:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Пробовал выделять больше памяти, эффект тот же..
Интересует общая технология выделения памяти и инициализация таких массивов в данном случае... smile 
PM MAIL   Вверх
zkv
Дата 21.5.2007, 00:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(INHazeR @  21.5.2007,  00:54 Найти цитируемый пост)
Пробовал выделять больше памяти, эффект тот же..

а это делали:
Цитата(zkv @  21.5.2007,  00:49 Найти цитируемый пост)
в конец добавляйте нуль-символ ('\0' или просто 0), по нему функции определяют конец строки.


Цитата(INHazeR @  21.5.2007,  00:54 Найти цитируемый пост)
Интересует общая технология выделения памяти и инициализация таких массивов в данном случае...

ммм.. Какая такая общая технология? 
Это что ли:
Код

char *pChar = new char[10];
delete pChar;

?
PM MAIL   Вверх
Xenon
Дата 21.5.2007, 01:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



zkv, ?
Код
char *pChar = new char[10];
delete [] pChar;


Или это ирония была? smile

Это сообщение отредактировал(а) Xenon - 21.5.2007, 01:59


--------------------
user posted image  
PM MAIL   Вверх
zkv
Дата 21.5.2007, 02:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



Цитата(Xenon @  21.5.2007,  01:59 Найти цитируемый пост)
Или это ирония была?

вроде не иронизировал, человек спросил про общую технологию выделения памяти, ну я ответил вообщем  smile 
или ты про оператор delete[]? Да, ошибочка вышла smile Сенкс за поправку
PM MAIL   Вверх
jonie
Дата 21.5.2007, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата

или ты про оператор delete[]? Да, ошибочка вышла  Сенкс за поправку
да ладно ошибка? гдей-та... для простых типов вполне можно вызывать и так, ибо new выделит блок для собственно данных и блок информации о выделенном, а delete уничтожит по блоку информации. Не станет он "уничтожать часть".... delete[] пишется для сложных типов - чтобы были вызваны деструкторы, а не банально "отобрана" память.......
в общем могу, конечно, и ошибаться....


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
Anikmar
Дата 21.5.2007, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(jonie @  21.5.2007,  10:22 Найти цитируемый пост)
да ладно ошибка? гдей-та... для простых типов вполне можно вызывать и так, ибо new выделит блок для собственно данных и блок информации о выделенном, а delete уничтожит по блоку информации. Не станет он "уничтожать часть".... delete[] пишется для сложных типов - чтобы были вызваны деструкторы, а не банально "отобрана" память.......
в общем могу, конечно, и ошибаться.... 

Нет, вы не ошибаетесь. Но лучше все равно вызывать delete[]. Чтобы была железная привычка. Это полезно, если при написании программы захочется использовать не простой тип, а собственный. И можно забыть, что освободждалась память "по-простому", появится утечка.
PM MAIL ICQ   Вверх
Daevaorn
Дата 21.5.2007, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

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



Цитата(jonie @  21.5.2007,  11:22 Найти цитируемый пост)
да ладно ошибка? гдей-та... для простых типов вполне можно вызывать и так, ибо new выделит блок для собственно данных и блок информации о выделенном, а delete уничтожит по блоку информации. Не станет он "уничтожать часть".... delete[] пишется для сложных типов - чтобы были вызваны деструкторы, а не банально "отобрана" память.......в общем могу, конечно, и ошибаться....

new/delete и new[]/delete[] - все другие комбинации UB и ошибка всегда.
PM MAIL WWW   Вверх
Anikmar
Дата 21.5.2007, 10:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Daevaorn @  21.5.2007,  10:29 Найти цитируемый пост)
new/delete и new[]/delete[] - все другие комбинации UB и ошибка всегда. 

Если брать Билдер с запущенным CodeGuardom, то на простых типах
Код

int *b;
b = new int[100];
delete b;

Ошибки утечки не возникает, только предупреждение.
А если использовать свой тип - то возникает утечка.

Тем не менее так делать не надо, разные компиляторы возможно ведут себя по-разному. Хотя я не помню что написано в стандарте по этому поводу, но точно помню, что в литературе по простым типам иногда делалась поблажка - может быть поэтому такое мнение и витает, что на простых типах ошибки нет.
PM MAIL ICQ   Вверх
Xenon
Дата 21.5.2007, 12:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Начинается ... Где-то мы уже об этом спорили с Earnest smile Если утечки не случилось 3,4,5 раз, это не значит, что ее не случится в 32 smile Это UB и все.
Даже тему нашел http://forum.vingrad.ru/forum/topic-144984/15.html


--------------------
user posted image  
PM MAIL   Вверх
INHazeR
Дата 21.5.2007, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Гм. Все-таки непонятно, как по данному адресу (переданному в параметре функции) выделить память и заполнить ее значениями. Варианты типа
void Foo(char* s, int* p)
Код

{
    s = "lala";
    s = "lala\0";
    s = new char[4];
}


не годятся, насколько я понимаю, так как адрес (s) сам по себе неизменен, этот указатель создали где-то вне функции и передали сюда, так что присваивать ему новое значение внутри функции бессмысленно, разве не так? При выходе из функции он снова примет прежнее значение, а выделенная нами память останется мертвым грузом где-то в куче.
По-моему, необходимо выделить память по заданному адресу, а не найти память и присвоить адрес начального байта этой памяти в указатель... или я ошибаюсь?
PM MAIL   Вверх
Daevaorn
Дата 21.5.2007, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

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



INHazeR
Код

//...
void f( int*& p )
{
   p = new int( 777 );
}
//...
int* p = 0;
f( p );
*p; //==777
///...
delete p;

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


Эксперт
****


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

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



Цитата(Xenon @  21.5.2007,  12:13 Найти цитируемый пост)
Начинается ... Где-то мы уже об этом спорили с Earnest  Если утечки не случилось 3,4,5 раз, это не значит, что ее не случится в 32  Это UB и все.
Даже тему нашел http://forum.vingrad.ru/forum/topic-144984/15.html 


Ничего не начинается, вы что думаете, что я буду отстаивать такую точку зрения? Я просто говорю про конкретное поведение того же Билдера, думаю, в остальных компиляторах будет также - блок удалится, но так делать НЕ НАДО.

Можно, конечно, асмовский код посмотреть. Но думаю, что с точки зрения менеджера памяти - ему все равно, что в этом блоке памяти находится, он его будет идентифицировать по адресу, поэтому удалить должен.

Но это - все равно пурга, если выделили память new[] то удалять надо delete[] без всяких там предположений.
Так что, Xenon, вы полностью правы и спорить я даже не собирался - но в литературе, действительно, встречается такая ерундень - типа для базовых типов большого значения не имеет delete использовать или delete[].

К сожалению моего английского не хватает точно перевести соответствующую главу стандарта, но мне кажется что именно UB там не значится (но спорить не буду - не уверен).
PM MAIL ICQ   Вверх
Xenon
Дата 21.5.2007, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Anikmar, ну просто предпосылки к спору с Daevaorn были, поэтому я уже воскинул руки к небу, а то уже которая тема религиозных войн ... наболело просто smile
А которая глава стандарта? Я просто в стандарте не смотрел.


--------------------
user posted image  
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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