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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как правильно инициализировать char*? Правильная методика инициализации char* 
:(
    Опции темы
Zerstroer
Дата 27.9.2015, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Здравствуйте!
Задумался над совершенно нубским вопросом.
Есть структура вида:

Код

struct MyStruct {
    char* field;
}


Есть функция, куда экземпляр этой структуры передается по указателю:


Код

MyStruct myStr;
int MyFunction(MyStruct &myStr){
}


Внутри функции для поля field память может быть выделена, а может быть и не выделена. Точно процесс проконтролировать невозможно.
Но, во избежание утечки памяти после вызова MyFunction я вынужден освободить память с помощью free(). Я понимаю, что free должен выполняться как можно ближе к выделению памяти malloc(), но в данном случае реализовать это я не могу - malloc() возможно вызывается в MyFunction, а возможно нет.
Я пробую решить эту задачу предварительной инициализацией MyStruct. 

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

Я пробую делать 
Код

myStr.field = malloc(0); 

перед вызовом MyFunction. Насколько это верное решение?

p.s. 
Прошу прощения, поторопился, и возможно разместил пост не в той ветке. Возможно, пост лучше переместить в "Общие вопросы" или "Вопросы для новичков".


Это сообщение отредактировал(а) Zerstroer - 27.9.2015, 20:40


--------------------
In silico
PM MAIL ICQ   Вверх
Zerstroer
Дата 27.9.2015, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Так, кажется, я совсем замаялся.
Из головы вылетело, что можно инициализировать NULLом!

Код

myStr.field = NULL;


Не пойдет.
Выяснил, что внутри функции возможен вызов такой вот строки:
printf("%i %s\n", strlen(mystr->field), mysqr->field);

Пока экспериментальным путем пришел к инициализации через malloc(0), но при вызове printf в функции - выводится ересь.

Это сообщение отредактировал(а) Zerstroer - 27.9.2015, 21:31


--------------------
In silico
PM MAIL ICQ   Вверх
xvr
Дата 27.9.2015, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(Zerstroer @  27.9.2015,  20:38 Найти цитируемый пост)
 Насколько это верное решение?

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

Проинициализируйте поле каким нибудь валидным указателем, а после возврата из функции проверьте его - если он изменился, то функция перебила его malloc'ом, и значит нужно звать free

PS. Тему перенес

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


Опытный
**


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

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



Цитата(xvr @  27.9.2015,  19:41 Найти цитируемый пост)
Проинициализируйте поле каким нибудь валидным указателем
 извините, недопонял Вас. Вы имеете ввиду присвоить указателю какое-либо значение? Что вы имеете ввиду под валидным указателем?
Вот это подойдет:
Код

myStr.field = malloc(1);
strcpy(myStr.field, "");



--------------------
In silico
PM MAIL ICQ   Вверх
jsharp36
Дата 28.9.2015, 00:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



не сиплюсплюсник, надеюсь кто поумнее поправит. А я дам древние советы.

1. Очень желательно память выделять и освобождать в одной и той же области.
2. Есть всякие умные указатели, лучше их использовать и не заботиться об освобождении.
3. Если 1 совет не получается, 2 не хочется, то всегда надо иницилизировать указатель, после освобождения обнулять. Просто как правило, чтобы нигде не допустить ошибку. Т.е.

Код

myStr.field = 0; // то же что и NULL
...
// разные вызовы
...
if (myStr.field)
{
    free(myStr.field);
    myStr.field = 0; // не забывайте обнулить после любого освобождения, чтобы случайно не обратиться к освобожденной памяти.
}



Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
feodorv
Дата 28.9.2015, 01:01 (ссылка)  | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(Zerstroer @  27.9.2015,  22:11 Найти цитируемый пост)
Вот это подойдет:

А Вы перед тем как
Цитата(Zerstroer @  27.9.2015,  20:38 Найти цитируемый пост)
Внутри функции для поля field память может быть выделена
free на этот malloc(1) делаете? Иначе утечка памяти.



Цитата(Zerstroer @  27.9.2015,  22:11 Найти цитируемый пост)
Что вы имеете ввиду под валидным указателем?
Ну, например, можно так:
Код

const char * const dummyString = "";
...
myStr.field = (char *) dummyString;
...
if( myStr.field != (char *) dummyString )
{
  free( myStr.field );
  myStr.field = (char *) dummyString;
}



Цитата(Zerstroer @  27.9.2015,  21:11 Найти цитируемый пост)
Не пойдет.
Выяснил, что внутри функции возможен вызов такой вот строки:
printf("%i %s\n", strlen(mystr->field), mysqr->field);

Всегда же можно проверить на NULL:
Код
if( mystr->field == NULL )
  printf("%i %s\n", strlen(""), "");
else
  printf("%i %s\n", strlen(mystr->field), mystr->field);



Цитата(Zerstroer @  27.9.2015,  20:38 Найти цитируемый пост)
Есть функция, куда экземпляр этой структуры передается по указателю:

& - это по ссылке)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
SVN74
Дата 30.9.2015, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Может вам через конструктор?
Код

struct MyStruct
{
    char* field;
    MyStruct()
    {
        field = ":)";
    }
};

В вашем случае наверно надо нечто подобное:
Код

struct MyStruct
{
    private:
     char* ptr;
    public:
     char* field;
    MyStruct()
    {
        field = new char[256];
        memset((void*)field, 0, 256);
        ptr = field;
    }
    ~MyStruct()
    {
       if(field != ptr)
       {
            delete [] field;
            delete [] ptr;
       }
       else
       {
            delete [] ptr;
       }
    }
};


Это сообщение отредактировал(а) SVN74 - 1.10.2015, 12:03
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

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

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

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

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


 




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


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

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