Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Сохранение локальной переменной

842
06 декабря 2008 года
sigmov
301 / / 16.09.2008
Необычное задание.
Есть некая функция.
 
Код:
void* PAS( int t)
{
    return &t;
}


Результат ~ я имею указатель на пустое место, ибо локальная переменная t была деконструирована по завершению функции.

А мне по заданию необходимо использовать этот указатель.

Ограничения:
параметр функции нельзя заменить на int& или int*.
нельзя выделять новую память.
[ например return memcpy(malloc(sizeof(int)),&t,sizeof(int)) ]
нельзя объявлять статические переменные
[ static int f = t ; return &f ; ]

И вот в чем дело: надо каким-то образом заблокировать удаление(деструктуризацию) из памяти локальной переменной t, оставив за ней память.
Тогда и из возвращенного указателя я смогу получить значение.
42K
06 декабря 2008 года
Increaser
17 / / 24.11.2008
Код:
const int n = 5;
...
vector<int> mas1;
int num;
for(int i=0;i<n;i++){
cin>>num;
mas1.push_back(num);
}
// допустим ввели массив 1 5 5 5 5
 for(int i=0;i<mas1.size();i++)
       if (mas1 == 5)
       {mas1.erase(mas1.begin() + i); }

for(int i=0;i<mas1.size(); i++){
cout<<mas1<<" ";
};
// выводит 1 5 5
// хотя должен вывести только 1.
// в чем дело?
307
06 декабря 2008 года
Artem_3A
863 / / 11.04.2008
Цитата: sigmov
Необычное задание.
Есть некая функция.
 
Код:
void* PAS( int t)
{
    return &t;
}


Результат ~ я имею указатель на пустое место, ибо локальная переменная t была деконструирована по завершению функции.

А мне по заданию необходимо использовать этот указатель.

Ограничения:
параметр функции нельзя заменить на int& или int*.
нельзя выделять новую память.
[ например return memcpy(malloc(sizeof(int)),&t,sizeof(int)) ]
нельзя объявлять статические переменные
[ static int f = t ; return &f ; ]

И вот в чем дело: надо каким-то образом заблокировать удаление(деструктуризацию) из памяти локальной переменной t, оставив за ней память.
Тогда и из возвращенного указателя я смогу получить значение.



Верни из функции не ссылку а значение.
то есть

 
Код:
void* fnFunction(int iParam, .......)
{
    .............
    .............
    return iParam;
}

Зы: что, задание прям так и звучит?
307
06 декабря 2008 года
Artem_3A
863 / / 11.04.2008
Цитата: Increaser
Код:
const int n = 5;
...
vector<int> mas1;
int num;
for(int i=0;i<n;i++){
cin>>num;
mas1.push_back(num);
}
// допустим ввели массив 1 5 5 5 5
 for(int i=0;i<mas1.size();i++)
       if (mas1 == 5)
       {mas1.erase(mas1.begin() + i); }

for(int i=0;i<mas1.size(); i++){
cout<<mas1<<" ";
};
// выводит 1 5 5
// хотя должен вывести только 1.
// в чем дело?



Дело в том что при каждом удалении размер вектора уменьшается на 1, следовательно mas1.size() после каждого удаления возвращает значение на 1 меньше, в результате цикл проходит меньше итераций чем тебе хотелось бы, решением послужит код типа:

 
Код:
for(int i=0;i<mas1.size();i++)
       if (mas1 == 5)
       {
                mas1.erase(mas1.begin() + i);
                i=0;
           }
288
06 декабря 2008 года
nikitozz
1.2K / / 09.03.2007
Цитата: sigmov
Необычное задание.
Есть некая функция.



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

842
06 декабря 2008 года
sigmov
301 / / 16.09.2008
Цитата: nikitozz
Это действительно такое задание или способ реализовать что-то. Если второе, то это не самый удачный способ.
Можно помучиться и действительно оставить эту переменную там, где она есть, чтобы на нее можно было указывать. Но стоит ли это делать?

Возможно вы правы. Дело в том, что если данный объект не удасться зафиксировать в памяти, то мне придется производить на 2 дейтсвия больше.
1) Выделить память под размер объекта.
2) Побитово скопировать объект в выделенную память

 
Код:
return memcpy(malloc(sizeof(gtype)),&var,sizeof(gtype))

(gtype var) - передаваемый параметр.

И самое главное, ведь это уже было сделано автоматически при передаче параметра в функцию( т.е под объект была выделена память и он был скопирован). А после выхода из функции процессор еще и будет вынужден осводить память где находилась var.

Как вы понимаете, это пагубно скажется на скорости. Когда объектов 10000000 это еще ничего.
Но вот если 10^9(10,11) то хоть на стенку лезь.

А всего-то нужно запретит автоматическое освобождение памяти, где хранится переменная(gtype var)
288
06 декабря 2008 года
nikitozz
1.2K / / 09.03.2007
Цитата: sigmov

А всего-то нужно запретит автоматическое освобождение памяти, где хранится переменная(gtype var)



Мда. Вообще, если вы хотите обработать такое количество объектов, то сомневаюсь, что это вас спасет.
А вообще я пока не совсем могу понять, зачем получать адрес переменной, которую вы передали в функцию? Расскажите в чем собственно состоит задача, и, возможно, найдется более элегантное решение.

842
06 декабря 2008 года
sigmov
301 / / 16.09.2008
Цитата:
Мда. Вообще, если вы хотите обработать такое количество объектов, то сомневаюсь, что это вас спасет.

Спасет.

Цитата:
А вообще я пока не совсем могу понять, зачем получать адрес переменной, которую вы передали в функцию?

Вот тут та и подвох - адрес точной копии.

Цитата:
Расскажите в чем собственно состоит задача, и, возможно, найдется более элегантное решение.


Задача: реализовать максимально скоростной динамический массив C#. Т.е. сооветственно массив должен уметь сужаться и расширятся по торебованию.
Лучшему создателю - 2хЗачет+1хЭкзамен(5)+Уважуха.
Все сокурсники принялись описывать что-то типа класса с 2 массивами, из которых второй по требованию расширяется, затем все элементы первого перезаписываются во второй ну и т.д.
Я же рашил использовать unmanaged C++ std::vector.
Но вектор не может хранить managed структуры.
Поэтому он хранит указатели на данные объекты.

Код:
namespace STL {
    generic<typename gtype>
    public ref class Vector
    {
    protected:
        System::Type ^TY;   //Получаем тип для извлечения managed объектов
        vector<void*> *Vec; //Храним наши указатели
    public:                                                                    
        Vector(System::Type ^TYPE)          {   TY=TYPE;    Vec = new vector<void*>(); }
    public:
        INL void clear()                    {   Vec->clear();   }
        INL Boolean empty()                 {   return Vec->empty();    }
        INL int size()                      {   return Vec->size();     }
       
        INL void push_back(gtype var)      
        {   //Вот сдеся лишнее выделение памяти
            Vec->push_back(memcpy(malloc(sizeof(gtype)),&var,sizeof(gtype)));
            //В идеале было бы заменить его Vec->push_back((PVOID)&var)
        }      
        INL void pop_back()                 {   Vec->pop_back();        }

        INL void insert(int pos, gtype var)
        {   //И сдесь
            if(pos<Vec->size())
            {
                Vec->insert(Vec->begin()+pos,memcpy(malloc(sizeof(gtype)),&var,sizeof(gtype)));
            }
        }
        INL void erase (int pos)            {   if(pos<Vec->size()) Vec->erase(Vec->begin()+pos);   }
       
        INL gtype back()                    {   return (gtype)Marshal::PtrToStructure((IntPtr)Vec->back(),TY);      }
        INL PVOID back(PVOID __null)        {   return Vec->back();     }
        INL gtype front()                   {   return (gtype)Marshal::PtrToStructure((IntPtr)Vec->front(),TY);     }
        INL PVOID front(PVOID __null)       {   return Vec->front();    }
        INL gtype at(REG int pos)                   {   return (gtype)Marshal::PtrToStructure((IntPtr)Vec->at(pos),TY);     }
        INL PVOID at(REG int pos,PVOID __null)      {   return Vec->at(pos);    }
    };
}
505
06 декабря 2008 года
vAC
343 / / 28.02.2006
Ничего кроме передачи параметра по ссылке здесь и не нужно.
Всю остальную работу за вас сделает компилятор, оптимизировав код.
842
06 декабря 2008 года
sigmov
301 / / 16.09.2008
Цитата: vAC
Ничего кроме передачи параметра по ссылке здесь и не нужно.
Всю остальную работу за вас сделает компилятор, оптимизировав код.


Вы должно быть имеете ввиду:

 
Код:
inline void push_back(cli::interior_ptr<gtype> var)    
        {  
            Vec->push_back((void*)var);
        }

error C2440: 'type cast' : cannot convert from 'cli::interior_ptr<Type>' to 'void *'
Компилятор не понимает что var это адресс реального объекта. Он считает что var - это объект. А на самом деле объект - это var*.
Кроме того, в этом случае мы размещаем в векторе не указатель на копию, а указатель на исходник - что неправильно.
341
07 декабря 2008 года
Der Meister
874 / / 21.12.2007
Цитата:
Задача: реализовать максимально скоростной динамический массив C#. Т.е. сооветственно массив должен уметь сужаться и расширятся по торебованию.
Лучшему создателю - 2хЗачет+1хЭкзамен(5)+Уважуха.

 
Код:
int * Method()
{
    int n = 3;
    return PAS(n);
}
Как тут что можно зафиксировать вообще?
Мужик, сила не в неуправляемом коде, забей на vector. Делай гибрид связанного списка и массива средствами C#: узлом списка может быть не только одно значение, но и несколько.
341
07 декабря 2008 года
Der Meister
874 / / 21.12.2007
[QUOTE=Der Meister]Делай гибрид связанного списка и массива средствами C#: узлом списка может быть не только одно значение, но и несколько.[/QUOTE]И System.Collections.Generic.LinkedList<T[]> тебе в помосч.
842
07 декабря 2008 года
sigmov
301 / / 16.09.2008
Цитата: Der Meister

Мужик, сила не в неуправляемом коде, забей на vector. Делай гибрид связанного списка и массива средствами C#: узлом списка может быть не только одно значение, но и несколько.


Дело в том, что С++ я 2 года изучаю, а С# только 2 мес. Потому и пытаюсь все к С++ привязать.

За совет спасибо.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог