crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Тема закрытаНачать новую тему
> Время жизни переменных, не понимаю одного момента
Litkevich Yuriy
  опции профиля:
сообщение 2.2.2008, 16:24
Сообщение #1


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Переменные созданные внутри функций живут пока мы невышли из фукции, так вроде.
Видел такую вещь:
int* func (foo foovar)
{
int foodim[8];
...
...
...
return foodim;
}

т.е. функция возвращает указатель на масив, который в ней же создан. Но покинув функцию масив прекратит существование и указатель будет показывать в кучу проги, например, может показывать в неосмысленное место.
Я правильно понимаю, т.е. это косячек програмиста, или как-то это иначе работает применительно просто к C++?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
archimed7592
  опции профиля:
сообщение 2.2.2008, 16:30
Сообщение #2


Участник
**

Группа: Участник
Сообщений: 127
Регистрация: 27.12.2007
Из: Moscow
Пользователь №: 56

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Litkevich Yuriy @ 2.2.2008, 16:24) *
Я правильно понимаю, т.е. это косячек програмиста,
Угу, косячек.

Цитата(Litkevich Yuriy @ 2.2.2008, 16:24) *
как-то это иначе работает применительно просто к C++?
Не то чтобы. Просто, как правило, автоматические объекты хранятся на стеке и при возврате из ф-ции стек никуда не девается, но, при вызове других ф-ций(к примеру), на то место, где был этот массив будет отображена какая-нибудь другая переменная.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.2.2008, 16:39
Сообщение #3


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Т.е. если мы делаем так:
int *pntr;
int  b;
pntr = func(foovar);
b=pntr[2];

т.е. воспользовались масивом сразу, это всегда будет давать один и тот же рузультат, тогда это наормально, я правильно понял, да?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
archimed7592
  опции профиля:
сообщение 2.2.2008, 16:43
Сообщение #4


Участник
**

Группа: Участник
Сообщений: 127
Регистрация: 27.12.2007
Из: Moscow
Пользователь №: 56

Спасибо сказали: 0 раз(а)




Репутация:   0  


Нет, это не гарантируется. Я тебе рассказал как это работает "в общем". Частных случаев может быть туева хуча. Грубо говоря, сегодня компилятор сделает как ты предполагал, завтра - что-нибудь где-нибудь соптимизирует и будешь вылавливать баг.

По идее нормальный компилятор должен ругнуться на такое(возвращение ссылки/указателя на локальный объект) warning'ом.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.2.2008, 17:07
Сообщение #5


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


понял, значит я не зря переписал этот кусок кода, в следующий вриант:

int (foo foovar, int *p, int cnt)
{
...
p[0]=foo1;
p[1]=foo2;
p[2]=foo3;
...
}

// где то дальше по коду
....
const int MAX=8;
int foodim[MAX];
int  b;
func(foovar, foodim, MAX);
b=foodim[2];


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

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

А было так, что функция сама формировала масив и возвращала указатель на него.

Сообщение отредактировал Litkevich Yuriy - 2.2.2008, 17:07
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
archimed7592
  опции профиля:
сообщение 2.2.2008, 17:41
Сообщение #6


Участник
**

Группа: Участник
Сообщений: 127
Регистрация: 27.12.2007
Из: Moscow
Пользователь №: 56

Спасибо сказали: 0 раз(а)




Репутация:   0  


Litkevich Yuriy,
Цитата(Litkevich Yuriy @ 2.2.2008, 17:07) *
А было так, что функция сама формировала масив и возвращала указатель на него.
С точки зрения проектирования хорошего(удобного) интерфейса было всё правильно(кроме реализации).
Я бы оставил как есть, за исключением того, что возвращал бы умный указатель(какой именно - зависит от специфики ф-ции) на динамически созданный объект(из соображений эффективности можно воспользоваться пулом для таких маленьких объектов).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.2.2008, 20:26
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(archimed7592 @ 2.2.2008, 20:41) *
умный указатель

Много раз слышал такую фразу, но незнаю, что это такое, может прояснишь?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
archimed7592
  опции профиля:
сообщение 2.2.2008, 20:35
Сообщение #8


Участник
**

Группа: Участник
Сообщений: 127
Регистрация: 27.12.2007
Из: Moscow
Пользователь №: 56

Спасибо сказали: 0 раз(а)




Репутация:   0  


Самый примитивный пример, не требующий особых телодвижений аля скачивания boost:
#include <memory>

class SomeBigClass
{ /* ... */ };

std::auto_ptr< SomeBigClass > someFunc()
{
    std::auto_ptr< SomeBigClass > ptr(new SomeBigClass(/* ... */));
    // ...
    return ptr;
}

Теперь если просто вызвать эту ф-цию вот так: someFunc(); то утечки не будет т.к. деструктор auto_ptr удалит объект.

Называется это дело RAII(ru, en).

Если хочешь подробнее об умных указателях, то почитай здесь, у Мейрса, у Александреску, у Саттера.

Сообщение отредактировал archimed7592 - 2.2.2008, 20:37
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 2.2.2008, 20:48
Сообщение #9


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(archimed7592 @ 2.2.2008, 23:35) *
Александреску

хотел купить его книгу по шаблонам проектирования и С++, но в продаже не нашел, в инете, я так понял ожидается переиздание.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 4.2.2008, 11:16
Сообщение #10


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


А вот auto_ptr с массивом использовать не надо - убъёть! :)

Litkevich Yuriy Проще всего переделать код на использование vector<int>.
С ним твоя исходная функция будет выглядеть так:
vector<int> func (foo foovar)
{
  vector<int> foodim;
  ...
  return foodim;
}

А использовать её будешь так:
vector<int> pntr;
int  b;
pntr = func(foovar);
b=pntr[2];

Написано об этом очень хорошо у Страуструпа в самом начале "Язык программирования С++ 3ед." - книжка, которую каждый уважающий себя программист на С++ должен прочитать и понять. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Тема закрытаНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 17.4.2024, 2:05