LINUX.ORG.RU

Передать ссылку массива!С++


0

0

Доброго время суток!
У меня такая проблема:
Частичный код программы:
...
int *U=new int[m];
...
int munic(int *U,int n)
{
int *V;
V = new int[n];
....
return(V);
}
main()
{
int *V=new int[n];
*V=munic(U,n);
for(int i=0; i<n;i++){cout<<V[n];}//выдает не массив (как хотелось)
return 0;
}
Подскажите плз как правильно вирнуть массив.
Заранее спасибо!

>>int munic(int *U,int n)

функция, возвращающая переменную int

>>*V=munic(U,n);


первому элементу массива присвоено возвращённое из munic() значение.

--

Надо:

int* munic(int *U,int n)

..

V=munic(U,n);

alex_custov ★★★★★
()

Если C++, то используйте стандартную библиотеку C++, не надо писать C-шный код на плюсах.

std::vector<int> munic(const std::vector<int> & U, int n)
{
    std::vector<int> result(n);

    //...

    return result;
}

P1XeL
()

И память у вас утекает:

внутри munic:
int *V; 
V = new int[n];


внутри main:
int *V=new int[n]; 
V=munic(U,n);

P1XeL
()
Ответ на: комментарий от P1XeL

а вы юморист, ничего так, что у вас лишнее копирование всего вектора? не считая того, чтоб работа с массивом по определению более быстрая( а код компактнее и читабельнее ), вектор хорош там, где надо динамически менять размер структуры, если этого делать не надо - в большинстве случаев можно обойтись и без него

lester ★★★★
()
Ответ на: комментарий от lester

> а вы юморист, ничего так, что у вас лишнее копирование всего вектора?

я думаю что именно в случае топикстартера, это не имеет абсолютно никакого значения.

smh ★★★
()

// вот это код на C++, который "возвращает массив из функции" и печатает его в стдаут; а не то что Вы написали.


#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;

typedef std::vector<int> IntArray;

IntArray* munic(size_t n)
{
  return new IntArray(n);
}

int main()
{
  IntArray *a = munic(500);
  copy(a->begin(), a->end(), ostream_iterator<int>(cout, " "));
  cout << endl;
  delete a;
  return 0;
}

d_a ★★★★★
()
Ответ на: комментарий от namezys

Интересно а есть в C++ что-то типа

DefVal<int,-1> xxx;

чтоб xxx прикидывался интом с умолчательным значением -1?

no1sm ★★
()
Ответ на: комментарий от namezys

// можно и автоптр (если осторожно).

int main()
{
  auto_ptr<IntArray> a(munic(500));
  copy(a->begin(), a->end(), ostream_iterator<int>(cout, " "));
  cout << endl;
  return 0;
}

// Этот код содержит очень мало темплейтов. Вы можете помочь проекту, добавив сюда темплейтов, и тогда в следующей версии можно будет грабить корованы.

d_a ★★★★★
()
Ответ на: комментарий от d_a

---------------------------------------------------------------

#include <vector>
#include <algorithm>
#include <iterator>
#include <iostream>
using namespace std;

typedef std::vector<int> IntArray;

IntArray* munic(size_t n)
{
  return new IntArray(n);
}

int main()
{
  auto_ptr<IntArray> a(munic(500));
  copy(a->begin(), a->end(), ostream_iterator<int>(cout, " "));
  cout << endl;
  delete a;
  return 0;
}

------------------------------------------------------

#include <iostream.h>

int main()
{
    int* a = new int[ 500 ];
    for( size_t i = 0 ; i < 500 ; ++i ) cout << a[ i ];
    cout << endl;
    delete[] a;
    return 0;    
}

lester ★★★★
()
Ответ на: комментарий от no1sm

// > чтоб xxx прикидывался интом с умолчательным значением -1?

// так что ли ?

template<typename T, int initval = -1>
struct DefVar
{
  explicit DefVar() : val_(initval) {}
  operator T() { return val_; }
  T val_;
};

// где то в программе
DefVar<int, -1> xxx;
DefVar<int , 3> yyy;
cout << xxx << endl; // -1
cout << xxx + 5 << endl; // 4 
cout << xxx + yyy << endl; // 2

d_a ★★★★★
()
Ответ на: комментарий от lester

> #include <iostream.h>
не по стандарту

> for( size_t i = 0 ; i < 500 ; ++i ) cout << a[ i ];
не печатается разделитель (пробел?) между элементами массива; в результате чего не понять где кончается одно число и начинается другое.

> int* a = new int[ 500 ];
>    for( size_t i = 0 ; i < 500 ; ++i ) cout << a[ i ];
магическое число 2 раза подряд; поменяли в одном месте -> в другом забыли -> полезли в чужую память.

вообще, Вы в курсе о проблемах, которые можно словить на свою голову при ручном программировании циклов?

d_a ★★★★★
()
Ответ на: комментарий от d_a

> не по стандарту

согласен

> не печатается разделитель (пробел?) между элементами массива;


тоже согласен, но добавить легко

> магическое число 2 раза подряд; поменяли в одном месте -> в другом забыли -> полезли в чужую память.


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

> вообще, Вы в курсе о проблемах, которые можно словить на свою голову при ручном программировании циклов?


вообще вы в курсе, что если надо например выделить память под хранение изображения( RGBA ), а потом продублировать изображение, или инвертировать значения и т.п.( вообщем где более-менее большой объем данных ) - то ваш пример отсасывает по полной?

Ваш код для примитивной операции тормознутый и громоздкий, KISS.

lester ★★★★
()
Ответ на: комментарий от lester

> вообще вы в курсе, что если надо например выделить память под хранение изображения( RGBA ), а потом продублировать изображение, или инвертировать значения и т.п.( вообщем где более-менее большой объем данных ) - то ваш пример отсасывает по полной?

Пардон; неосилил. Где вы в моем коде такой страшный оверхед нашли? Ткните пальцем. Может быть, в векторе? или в функции copy? или, неужто, в auto_ptr?

[hint] Вектор использует для хранения своих элементов непрерывный блок памяти, и, как следствие, обращение к его элементам не дороже обращения к элементам массива + достигается обратная совместимость с массивами; так что выделяйте, дублируйте, инвертируйте сколько душе угодно.

> Ваш код для примитивной операции тормознутый и громоздкий, KISS.

Бенчмарк в студию, из которого следует, что мой код тормознутый. Иначе это банальная "газификация луж" человеком, ниасилившим STL.

d_a ★★★★★
()
Ответ на: комментарий от lester

С -O3 лишнего копирования не будет. Работа с массивом не более быстра, а такая же, в случае с -O3 конечно же.

> в большинстве случаев можно обойтись и без него

А нужно ли? Писать код без new и malloc это хороший стиль. Разницы по производительности не будет, совместимость с Си кодом есть.

Reset ★★★★★
()
Ответ на: комментарий от d_a

Далеко идти не будем - то что от нас попросил автор топика:

TimeCounter counter;
int* A = new int[50000000];
size_t time1 = counter.GetInterval(); // 205 ms

counter.Clear();
std::vector<int> STLA( 50000000 );
size_t time2 = counter.GetInterval(); // 438 ms

lester ★★★★
()
Ответ на: комментарий от lester

А всё потому, что кое-кто не знает как работает вектор. Ты memset(A, 0, 50000000 * sizeof(int)) поставь в первом случае и скорость будет секунда в секунду.

Reset ★★★★★
()
Ответ на: комментарий от Reset

> А всё потому, что кое-кто не знает как работает вектор. Ты memset(A, 0, 50000000 * sizeof(int)) поставь в первом случае и скорость будет секунда в секунду.

накуя мне это делать?

lester ★★★★
()
Ответ на: комментарий от Reset

> Если тебе нужно только выделить память, то используй reserve.

и что я буду делать с вектором, который зарезервировал себе память, а по сути не содержит ни одного элемента?

lester ★★★★
()
Ответ на: комментарий от lester

Если программа работает менее 5 минут и при этом производятся
какие-то бенчмарки, то у меня складывается ощущение, что кто-то
кого-то хочет на2.71бать.


У меня получилось так:
$cat 1.cpp
#include <sys/time.h>

#include <iostream>
#include <vector>

double get_full_time()
{
        struct timeval tv;
        gettimeofday (&tv, 0);
        return (double) (tv.tv_sec * 100.0 + tv.tv_usec / 10000.0);
}


class Timer
{
        double t1_;

public:
        Timer() : t1_ (get_full_time() ) {}
        double elapsed()
        {
                return (get_full_time() - t1_) / 100.0;
        }
        void restart()
        {
                t1_ = get_full_time();
        }
};

int main()
{
        Timer t;
        int* A = new int[50000000];
        memset (A, 0, 50000000 * sizeof (int) );
        std::cout << t.elapsed() << "\n";

        t.restart();
        std::vector<int> STLA ( 50000000 );
        std::cout << t.elapsed() << "\n";

        std::cout << A << " " << &STLA[0] << "\n";
}

$g++ -O3 1.cpp

$./a.out
0.206331
0.184152
0x2b97315a7010 0x2b973d465010

Reset ★★★★★
()

вобщем для чистоты эксперимента жду:
- замер без memset( при загрузке/копировании и т.п. - мне инициализация в 0 не надо )
- замер с calloc - ну если уж и надо, то сделаем это проще - в одну операцию

lester ★★★★
()

о-ла-ла

counter.Clear();
for( size_t i = 0 ; i < 50000000 ; ++i ) sum += A[ i ];
size_t time3 = counter.GetInterval(); // 188 ms

counter.Clear();
for( std::vector<int>::iterator it = STLA.begin() ; it != STLA.end() ; ++it ) sum += *it;
size_t time4 = counter.GetInterval(); // 23642 ms

lester ★★★★
()
Ответ на: комментарий от lester

counter.Clear();
for( size_t i = 0 ; i < 50000000 ; ++i ) sum += STLA[ i ];
size_t time4 = counter.GetInterval(); // 1064 ms

И кто после этого газифицирует ;)

lester ★★★★
()
Ответ на: комментарий от d_a

> Бенчмарк в студию, из которого следует, что мой код тормознутый.

предоставлен, итого ваш пафос - это банальная "газификация луж" человеком, сующим куда ни попадя STL.

lester ★★★★
()
Ответ на: комментарий от lester

-O3 было случайно забыто ?

int main()
{
        Timer t;
        int* A = new int[50000000];
        memset (A, 0, 50000000 * sizeof (int) );
        std::cout << "new: " << t.elapsed() << "\n";

        t.restart();
        A = (int*) malloc (50000000 * sizeof (int) );
        memset (A, 0, 50000000 * sizeof (int) );
        std::cout << "malloc: " << t.elapsed() << "\n";

        t.restart();
        A = (int*) calloc (50000000, sizeof (int) );
        std::cout << "calloc: " << t.elapsed() << "\n";

        t.restart();
        std::vector<int> STLA ( 50000000 );
        std::cout << "vector: " << t.elapsed() << "\n";

        t.restart();
        double sum = 0.0;
        for ( int i = 0 ; i < 50000000 ; ++i ) sum += A[ i ];
        std::cout << "loop1: " << t.elapsed() << " " << sum << "\n";

        t.restart();
        sum = 0.0;
        for ( std::vector<int>::iterator it = STLA.begin(), e = STLA.end() ; it != e ; ++it )
                sum += *it;
        std::cout << "loop vec1: " << t.elapsed() << " " << sum << "\n";

        t.restart();
        sum = 0.0;
        for ( std::vector<int>::iterator it = STLA.begin() ; it != STLA.end() ; ++it )
                sum += *it;
        std::cout << "loop vec2: " << t.elapsed() << " " << sum << "\n";

        std::cout << A << " " << &STLA[0] << "\n";
}

./a.out
new: 0.208757
malloc: 0.208591
calloc: 2.70081e-05
vector: 0.184901
loop1: 0.439974 0
loop vec1: 0.287884 0
loop vec2: 0.287662 0

Reset ★★★★★
()
Ответ на: комментарий от d_a

> copy(a->begin(), a->end(), ostream_iterator<int>(cout, " "));

кстати на этой строке ваш пример собранный под оффтопиком вываливается с ошибкой ostream_iterator is not dereferenaceable

lester ★★★★
()
Ответ на: комментарий от Reset

Если double sum заменить на int sum то вообще интересно получается.


t.restart();
        sum = 0;
        for ( int i = 0  ; i < (int) STLA.size() ; ++i )
                sum += STLA[i];
        std::cout << "loop vec3: " << t.elapsed() << " " << sum << "\n";

./a.out
new: 0.206919
malloc: 0.204878
calloc: 2.30408e-05
vector: 0.183603
loop1: 0.197517 0
loop vec1: 0.059097 0
loop vec2: 0.067536 0
loop vec3: 0.0680179 0

Reset ★★★★★
()
Ответ на: комментарий от Reset

calloc видимо по каким-то причинам не проинициализировал страницы из-за этого loop1 оказался таким медленным

Reset ★★★★★
()
Ответ на: комментарий от lester

Ты из-за производительности в дебаге будешь жертвовать читабельностью кода и стабильностью в релизе ? Это идиотизм какой-то. Дебаг выполняется один раз, а сколько раз потом будет запускаться и работать релиз? А сколько потом человек будет читать и разбираться с твоим кодом ?

Reset ★★★★★
()
Ответ на: комментарий от lester

Вообще откуда такое время взялось? У меня даже с -O0 получается 1.67 секунд максимум. Прозреваю, что опять меня хотят где-то на2.71бать.

Reset ★★★★★
()
Ответ на: комментарий от Reset

> Ты из-за производительности в дебаге будешь жертвовать читабельностью кода и стабильностью в релизе ? Это идиотизм какой-то

идиотизм считать, что:

#define DATA_SIZE 500

typedef std::vector<int> IntArray;

IntArray* munic(size_t n)
{
return new IntArray(n);
}

int main()
{
auto_ptr<IntArray> a(munic(DATA_SIZE));
copy(a->begin(), a->end(), ostream_iterator<int>(cout, " "));
cout << endl;
delete a;
return 0;
}

читабельнее чем:

#include <iostream>
#define DATA_SIZE 500

int main()
{
int* a = new int[ DATA_SIZE ];
for( size_t i = 0 ; i < DATA_SIZE ; ++i ) cout << a[ i ];
cout << endl;
delete[] a;
return 0;
}

> стабильностью


стабильностью??? это еще откуда? создав структуру и положив туда размер + указатель мы не влияем на стабильность

lester ★★★★
()
Ответ на: комментарий от lester

> стабильностью??? это еще откуда? создав структуру и положив туда размер + указатель мы не влияем на стабильность

Удалять эту структуру кто у тебя будет? А потом вот из-за таких вот борющихся за "производительность" месяцами ловят утечки и сегфолты.

Reset ★★★★★
()
Ответ на: комментарий от Reset

> Удалять эту структуру кто у тебя будет? А потом вот из-за таких вот борющихся за "производительность" месяцами ловят утечки и сегфолты.

как ни странно delete, "потом вот из-за таких вот борющихся за "производительность" месяцами ловят утечки и сегфолты." - расскажи это сишникам( а также авторам КДЕ - "плазма не падает" ), при наличии головы на плечах, сразу при написании кода для выделения памяти пишется код для ее очистки

lester ★★★★
()
Ответ на: комментарий от Reset

> с дуру можно и %#й сломать

верю вам наслово

lester ★★★★
()
Ответ на: комментарий от Reset

> Уж не на древней ли студии запускался код? Вот ты и попалился :)

2008

lester ★★★★
()

я сейчас убегаю - буду ночью уже

lester ★★★★
()
Ответ на: комментарий от lester

delete не может застраховать от утечек. Кто-нибудь полезет своими кривым рученками делать рефакторинг (да даже ты сам) и уже забудешь про этот delete и где он стоял и кто его вызывал и всё, писец. А с исключениями как быть?

В общем не убедительно, скорость как мы выяснили не возрастает, а геморроя существенно добавляется.

Reset ★★★★★
()
Ответ на: комментарий от lester

> ( а также авторам КДЕ - "плазма не падает" )

Вот вот. Борются они за производительность. Ручками, а не средствами компилятора

namezys ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.