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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Еще раз про это - строки, возврат строки из функции 
V
    Опции темы
tatan
Дата 9.11.2007, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



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

Код

#include <cstdlib>
#include <iostream>
#include <string>


using namespace std;

char* fooChar()
{
      char* t = new char[21];
      t = "Common Vocabulary Words";
      return t;
};

string fooString()
{
       string s = "Common Vocabulary Words";
       return s;
};

int main(int argc, char *argv[])
{
    char* y;
    y = fooChar();
    cout << y << endl;
    delete [] y;
    
    string ss = fooString();
    cout << ss << endl;
        
    return 0;
}



Еще пара вопросов:

- правильно ли из функции передавать локальный указатель?
- правильно ли я освободил память?

Почитал по форуму, внятного ответа не увидел.
PM MAIL   Вверх
Sartorius
Дата 9.11.2007, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Код

char* fooChar()
{
      char* t = new char[21];  // выделяем память
      t = "Common Vocabulary Words";// присваиваем t указатель на литерал в ReadOnly области
      return t; // и возвращаем его. при это программа истекает 21-м байтом
};


 а вот для std::string operator= перегружет, так что в конечном счете будет выполняться копирование контента литерала  smile 

 Как делать - это дело вкуса и треболваний к производительности. Но в первом случае сделать memcpy() просто необходимо  smile 
PM MAIL ICQ   Вверх
tatan
Дата 9.11.2007, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



"будет выполняться копирование контента литерала" - что это значит?
Где необходимо сделать memcpy?
PM MAIL   Вверх
Sartorius
Дата 9.11.2007, 18:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Код

char* fooChar()
{
      char* t = new char[21];  
      memcpy(t,  "Common Vocabulary Words", size_t(21));
      return t; 
};

PM MAIL ICQ   Вверх
tatan
Дата 9.11.2007, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Понятно.
Функция будет получать строки сложным образом с дискаsmile

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


Эксперт
***


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

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



Код

const char* fooChar()
{
       return "Common Vocabulary Words";   // ничего нигде удалять не нужно
};

 // правильный вариант - использовать классы, а не массивы символов
string fooString()
{
       return "Common Vocabulary Words"; 
};

Цитата(tatan @  9.11.2007,  18:09 Найти цитируемый пост)
- правильно ли из функции передавать локальный указатель?

нет

Цитата(tatan @  9.11.2007,  18:09 Найти цитируемый пост)
- правильно ли я освободил память?

нет. 

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


Шустрый
*


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

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



to Fazil6

константная строка была взята для примера, внутри функции в любом случае будет работа с char *.
Вопрос в том что правильно возвращать - локальный string или локальный char*. И в чем ключевая разница в этих подходах.

И, если можно, подробней про неправильное освобождение памяти
PM MAIL   Вверх
Dims
Дата 9.11.2007, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(tatan @  9.11.2007,  18:09 Найти цитируемый пост)


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


Код

     char* t = new char[21];
     // завести в куче область длиной 21 байт и положить адрес начала этой области в переменную t


      t = "Common Vocabulary Words";
      // в памяти заведена постоянная область с символами "Common Vocabulary Words"; положить адрес начала этой области в переменную t, забыв при этом предыдущий адрес


       string s = "Common Vocabulary Words";
       // создать объект типа string инициализировав его заведённой в памяти постоянной областью с символами "Common Vocabulary Words"


    char* y;
    y = fooChar();
    cout << y << endl;
    delete [] y;
    // попытка освободить постоянную область памяти, а не кучу. ошибка!

    
    string ss = fooString();
    // создать объект типа string и скопировать в него объект, который вернулся из функции. неоптимально!



Цитата

- правильно ли из функции передавать локальный указатель?

Из функции передаётся значение переменной. В случае указателя -- это адрес. Сама переменная, в которой был указатель, уничтожается, а её содержимое копируется туда, откуда вызвана функция. Поскольку адрес занимает несколько байт, то это не накладно. Такие передачи не занимают машинного времени больше, чем просто вызов функции.

Цитата

- правильно ли я освободил память?

Ты освободил не ту память. Адрес той памяти, которую ты завёл оператором new ты забыл в тот момент, когда присвоил указателю адрес строки-константы.

Добавлено через 2 минуты и 51 секунду
Из функции МОЖНО передавать локальный указатель, если ты знаешь его происхождение. Например, если функция заводит внутри себя память и возвращает её адрес, то это допустимо. Главное -- не забыть её освободить.
PM MAIL   Вверх
tatan
Дата 9.11.2007, 23:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



to Dims

спасибо, начинаю понимать
PM MAIL   Вверх
Fazil6
Дата 10.11.2007, 01:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Dims @  9.11.2007,  22:54 Найти цитируемый пост)
Из функции МОЖНО передавать локальный указатель, если ты знаешь его происхождение. Например, если функция заводит внутри себя память и возвращает её адрес, то это допустимо. Главное -- не забыть её освободить.

да уж... Главное - это не делать так.
Цитата(Dims @  9.11.2007,  22:54 Найти цитируемый пост)
Из функции передаётся значение переменной. В случае указателя -- это адрес. Сама переменная, в которой был указатель, уничтожается, а её содержимое копируется туда, откуда вызвана функция. Поскольку адрес занимает несколько байт, то это не накладно. Такие передачи не занимают машинного времени больше, чем просто вызов функции.

главный фокус в том, на что этот указатель указывает. Откуда это взялось и кем и когда будет разрушено? Ненадо писать код функции так, что вызывающий код зависит от реализации внутри функции.
Код

string ss = fooString();
    // создать объект типа string и скопировать в него объект, который вернулся из функции. неоптимально!

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

Это сообщение отредактировал(а) Fazil6 - 10.11.2007, 01:56
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.0738 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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