Возвращение массива из функции
От: LA Jazz Россия  
Дата: 25.07.02 12:37
Оценка:
typedef struct
{
int e1;
int e2;
} sA;


Как лучше осуществить возвращение массива структур sA из ф-ии:

1.
void f(sA* pSA, int* count)
{
  int nmbSA = 4;
  ...
  sA *pRes = new sA[nmbSA];
  ... // do something with array
  pSA = pRes;
  *count = nmbSA;
}

main()
{
  int nmbSA = 0;
  sA *pSA = 0;
  f(pSA, &nmbSA);
  if(pSA)
    delete pSA;
}



2.
void f(sA* pSA, int count)
{
  int nmbSA = 4;
  ...
  sA *pRes = new sA[nmbSA];
  ... // do something with array
  memcpy(pSA, pRes, sizeof(sA)*(__min(nmbSA, count))
  delete pRes;
}

main()
{
  int nmbSA = 4;
  sA *pSA = new sA[nmbSA];
  f(pSA, nmbSA);
  delete pSA;
}
Re: Возвращение массива из функции
От: Gosha Украина  
Дата: 25.07.02 12:54
Оценка:
Здравствуйте LA Jazz, Вы писали:


LJ>typedef struct

LJ>{
LJ> int e1;
LJ> int e2;
LJ>} sA;


LJ>Как лучше осуществить возвращение массива структур sA из ф-ии:


LJ>1.

LJ>
LJ>void f(sA* pSA, int* count)
LJ>{
LJ>  int nmbSA = 4;
LJ>  ...
LJ>  sA *pRes = new sA[nmbSA];
LJ>  ... // do something with array
LJ>  pSA = pRes;
LJ>  *count = nmbSA;
LJ>}

LJ>main()
LJ>{
LJ>  int nmbSA = 0;
LJ>  sA *pSA = 0;
LJ>  f(pSA, &nmbSA);
LJ>  if(pSA)
LJ>    delete pSA;
LJ>}
LJ>



LJ>2.

LJ>
LJ>void f(sA* pSA, int count)
LJ>{
LJ>  int nmbSA = 4;
LJ>  ...
LJ>  sA *pRes = new sA[nmbSA];
LJ>  ... // do something with array
LJ>  memcpy(pSA, pRes, sizeof(sA)*(__min(nmbSA, count))
LJ>  delete pRes;
LJ>}

LJ>main()
LJ>{
LJ>  int nmbSA = 4;
LJ>  sA *pSA = new sA[nmbSA];
LJ>  f(pSA, nmbSA);
LJ>  delete pSA;
LJ>}
LJ>


А почему бы и не так:
sA* f(int count)
{
    sA* pSA = new sA[count];
    if (pSA){
        ...
        // do something with array
        ...
        return pSA;
    }else
        return NULL;
}

main()
{
    int nmbSA = 4;
    sA *pSA = f(nmbSA);
    if (pSA)
        delete pSA;
}
Re: Возвращение массива из функции
От: PSP Беларусь  
Дата: 25.07.02 12:54
Оценка:
Здравствуйте LA Jazz, Вы писали:


LJ>typedef struct

LJ>{
LJ> int e1;
LJ> int e2;
LJ>} sA;


LJ>Как лучше осуществить возвращение массива структур sA из ф-ии:


LJ>1.

LJ>
LJ>void f(sA* pSA, int* count)
LJ>{
LJ>  int nmbSA = 4;
LJ>  ...
LJ>  sA *pRes = new sA[nmbSA];
LJ>  ... // do something with array
LJ>  pSA = pRes;
LJ>  *count = nmbSA;
LJ>}

LJ>main()
LJ>{
LJ>  int nmbSA = 0;
LJ>  sA *pSA = 0;
LJ>  f(pSA, &nmbSA);
LJ>  if(pSA)
LJ>    delete pSA;
LJ>}
LJ>


Этот вариант неправильный. Вообще ничего не сохранится. pSA останется равным нулю.

LJ>2.

LJ>
LJ>void f(sA* pSA, int count)
LJ>{
LJ>  int nmbSA = 4;
LJ>  ...
LJ>  sA *pRes = new sA[nmbSA];
LJ>  ... // do something with array
LJ>  memcpy(pSA, pRes, sizeof(sA)*(__min(nmbSA, count))
LJ>  delete pRes;
LJ>}

LJ>main()
LJ>{
LJ>  int nmbSA = 4;
LJ>  sA *pSA = new sA[nmbSA];
LJ>  f(pSA, nmbSA);
LJ>  delete pSA;
LJ>}
LJ>

Это тоже некорректно.

корректно будет так:

void f(sA* & pSA, int &count)
{
  int nmbSA = 4;
  ...
  sA *pRes = new sA[nmbSA];
  ... // do something with array
  pSA = pRes;
  count = nmbSA;
}

main()
{
  int nmbSA = 0;
  sA *pSA = 0;
  f(pSA, nmbSA);
  if(pSA)
    delete pSA;
}
Всегда Ваш, PSP.
Re[2]: Возвращение массива из функции
От: LA Jazz Россия  
Дата: 25.07.02 12:56
Оценка:
Здравствуйте Gosha, Вы писали:

G>А почему бы и не так:


Можно и так.
Только размер массива станет известен только в функции.
Но можно и так.
Re[3]: Возвращение массива из функции
От: Gosha Украина  
Дата: 25.07.02 13:46
Оценка:
Здравствуйте LA Jazz, Вы писали:

LJ>Можно и так.

LJ>Только размер массива станет известен только в функции.
LJ>Но можно и так.

Ну, тогда легким движеним руки ...
sA* f(int &count)
{
    sA* pSA = new sA[count];
    if (pSA){
        ...
        // do something with array
        ...
        return pSA;
    }else{
        count=0;
        return NULL;
    }
} main()
{
    int nmbSA = 4;
    sA *pSA = f(nmbSA);
    if (pSA)
        delete pSA;
}
Re[4]: Возвращение массива из функции
От: LA Jazz Россия  
Дата: 25.07.02 13:51
Оценка:
Здравствуйте Gosha, Вы писали:

Но тогда возникает другой вопрос: этично ли заставлять пользователя удалять
указатель. Ведь так и забыть можно про удаление, а это Leaks...
Re[5]: Возвращение массива из функции
От: santucco  
Дата: 25.07.02 14:03
Оценка:
Здравствуйте LA Jazz, Вы писали:

LJ>Здравствуйте Gosha, Вы писали:


LJ>Но тогда возникает другой вопрос: этично ли заставлять пользователя удалять

LJ>указатель. Ведь так и забыть можно про удаление, а это Leaks...
Ну, откровенно говоря, возврат указателя на выделенную внутри функции памать — потенциальный memory leak, как бы он не возвращался — через в параметры или через возвращаемое значение )). User обязательно забудет вызвать delete для этой памяти.
Не стреляйте в пианиста, он играет как умеет...
Re[6]: Возвращение массива из функции
От: LA Jazz Россия  
Дата: 25.07.02 14:06
Оценка:
Здравствуйте santucco, Вы писали:

А как лучше вернуть массив, если заранее к-во элементов неизвестно
и не заставляя юзера delete делать?
Re[6]: Возвращение массива из функции
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 25.07.02 14:07
Оценка:
Здравствуйте santucco, Вы писали:

S>Здравствуйте LA Jazz, Вы писали:


LJ>>Здравствуйте Gosha, Вы писали:


LJ>>Но тогда возникает другой вопрос: этично ли заставлять пользователя удалять

LJ>>указатель. Ведь так и забыть можно про удаление, а это Leaks...
S>Ну, откровенно говоря, возврат указателя на выделенную внутри функции памать — потенциальный memory leak, как бы он не возвращался — через в параметры или через возвращаемое значение )). User обязательно забудет вызвать delete для этой памяти.

Ну так этим и WinAPI грешит, взять хотя бы FormatMessage c его флагом FORMAT_MESSAGE_ALLOCATE_BUFFER — освобождение выделенной памяти остается на вашей совести...
Re[7]: Возвращение массива из функции
От: santucco  
Дата: 25.07.02 14:20
Оценка:
Здравствуйте LA Jazz, Вы писали:

LJ>Здравствуйте santucco, Вы писали:


LJ>А как лучше вернуть массив, если заранее к-во элементов неизвестно

LJ>и не заставляя юзера delete делать?
Выделить заведомо больше памяти, передать в функцию указатель на память и ее размер и вернуть количество элементов, положенных в массив — это классический С-шный подход

Или взять STL-реализацию массива (vector), передать его в функцию по ссылке и не мучиться
Не стреляйте в пианиста, он играет как умеет...
Re[7]: Возвращение массива из функции
От: santucco  
Дата: 25.07.02 14:22
Оценка:
Здравствуйте Flamer, Вы писали:

F>Здравствуйте santucco, Вы писали:


S>>Здравствуйте LA Jazz, Вы писали:


LJ>>>Здравствуйте Gosha, Вы писали:


LJ>>>Но тогда возникает другой вопрос: этично ли заставлять пользователя удалять

LJ>>>указатель. Ведь так и забыть можно про удаление, а это Leaks...
S>>Ну, откровенно говоря, возврат указателя на выделенную внутри функции памать — потенциальный memory leak, как бы он не возвращался — через в параметры или через возвращаемое значение )). User обязательно забудет вызвать delete для этой памяти.

F>Ну так этим и WinAPI грешит, взять хотя бы FormatMessage c его флагом FORMAT_MESSAGE_ALLOCATE_BUFFER — освобождение выделенной памяти остается на вашей совести...

No comments
Не стреляйте в пианиста, он играет как умеет...
Re[8]: Возвращение массива из функции
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 25.07.02 14:25
Оценка:
Здравствуйте santucco, Вы писали:

S>Здравствуйте Flamer, Вы писали:


F>>Здравствуйте santucco, Вы писали:


S>>>Здравствуйте LA Jazz, Вы писали:


LJ>>>>Здравствуйте Gosha, Вы писали:


LJ>>>>Но тогда возникает другой вопрос: этично ли заставлять пользователя удалять

LJ>>>>указатель. Ведь так и забыть можно про удаление, а это Leaks...
S>>>Ну, откровенно говоря, возврат указателя на выделенную внутри функции памать — потенциальный memory leak, как бы он не возвращался — через в параметры или через возвращаемое значение )). User обязательно забудет вызвать delete для этой памяти.

F>>Ну так этим и WinAPI грешит, взять хотя бы FormatMessage c его флагом FORMAT_MESSAGE_ALLOCATE_BUFFER — освобождение выделенной памяти остается на вашей совести...

S>No comments

Не понял Что имелось в виду? Разъясните, плз..
Re[9]: Возвращение массива из функции
От: santucco  
Дата: 26.07.02 07:41
Оценка:
Здравствуйте Flamer, Вы писали:

F>Здравствуйте santucco, Вы писали:


S>>Здравствуйте Flamer, Вы писали:


F>>>Здравствуйте santucco, Вы писали:


S>>>>Здравствуйте LA Jazz, Вы писали:


LJ>>>>>Здравствуйте Gosha, Вы писали:


LJ>>>>>Но тогда возникает другой вопрос: этично ли заставлять пользователя удалять

LJ>>>>>указатель. Ведь так и забыть можно про удаление, а это Leaks...
S>>>>Ну, откровенно говоря, возврат указателя на выделенную внутри функции памать — потенциальный memory leak, как бы он не возвращался — через в параметры или через возвращаемое значение )). User обязательно забудет вызвать delete для этой памяти.

F>>>Ну так этим и WinAPI грешит, взять хотя бы FormatMessage c его флагом FORMAT_MESSAGE_ALLOCATE_BUFFER — освобождение выделенной памяти остается на вашей совести...

S>>No comments

F>Не понял Что имелось в виду? Разъясните, плз..

Имелось ввиду, что не стОит перенимать откровенно неудачные и потенциально опасные приемы, даже если они используются в чьем-либо API.
Не стреляйте в пианиста, он играет как умеет...
Re[10]: Возвращение массива из функции
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 26.07.02 07:45
Оценка:
Здравствуйте santucco, Вы писали:

S>Здравствуйте Flamer, Вы писали:


F>>Здравствуйте santucco, Вы писали:


S>>>Здравствуйте Flamer, Вы писали:


F>>>>Здравствуйте santucco, Вы писали:


S>>>>>Здравствуйте LA Jazz, Вы писали:


LJ>>>>>>Здравствуйте Gosha, Вы писали:


LJ>>>>>>Но тогда возникает другой вопрос: этично ли заставлять пользователя удалять

LJ>>>>>>указатель. Ведь так и забыть можно про удаление, а это Leaks...
S>>>>>Ну, откровенно говоря, возврат указателя на выделенную внутри функции памать — потенциальный memory leak, как бы он не возвращался — через в параметры или через возвращаемое значение )). User обязательно забудет вызвать delete для этой памяти.

F>>>>Ну так этим и WinAPI грешит, взять хотя бы FormatMessage c его флагом FORMAT_MESSAGE_ALLOCATE_BUFFER — освобождение выделенной памяти остается на вашей совести...

S>>>No comments

F>>Не понял Что имелось в виду? Разъясните, плз..

S>Имелось ввиду, что не стОит перенимать откровенно неудачные и потенциально опасные приемы, даже если они используются в чьем-либо API.

Так я вроде как согласен с этим
Re[2]: Возвращение массива из функции
От: m.a.g. Мальта http://dottedmag.net/
Дата: 26.07.02 08:11
Оценка: 8 (1)
Здравствуйте PSP, Вы писали:

PSP>корректно будет так:


PSP>
PSP>void f(sA* & pSA, int &count)
PSP>{
PSP>  sA *pRes = new sA[nmbSA];
PSP>  pSA = pRes;
PSP>}

PSP>main()
PSP>{
PSP>  f(pSA, nmbSA);
PSP>  if(pSA)
PSP>    delete pSA;
PSP>}

PSP>


То ли я туплю? Все делают одну и ту же ошибку. Удалять надо так:
delete [] pSA;
Re[11]: Возвращение массива из функции
От: santucco  
Дата: 26.07.02 08:15
Оценка:
Здравствуйте Flamer, Вы писали:

F>Здравствуйте santucco, Вы писали:


S>>Здравствуйте Flamer, Вы писали:


F>>>Здравствуйте santucco, Вы писали:


S>>>>Здравствуйте Flamer, Вы писали:


F>>>>>Здравствуйте santucco, Вы писали:


S>>>>>>Здравствуйте LA Jazz, Вы писали:


LJ>>>>>>>Здравствуйте Gosha, Вы писали:


LJ>>>>>>>Но тогда возникает другой вопрос: этично ли заставлять пользователя удалять

LJ>>>>>>>указатель. Ведь так и забыть можно про удаление, а это Leaks...
S>>>>>>Ну, откровенно говоря, возврат указателя на выделенную внутри функции памать — потенциальный memory leak, как бы он не возвращался — через в параметры или через возвращаемое значение )). User обязательно забудет вызвать delete для этой памяти.

F>>>>>Ну так этим и WinAPI грешит, взять хотя бы FormatMessage c его флагом FORMAT_MESSAGE_ALLOCATE_BUFFER — освобождение выделенной памяти остается на вашей совести...

S>>>>No comments

F>>>Не понял Что имелось в виду? Разъясните, плз..

S>>Имелось ввиду, что не стОит перенимать откровенно неудачные и потенциально опасные приемы, даже если они используются в чьем-либо API.

F>Так я вроде как согласен с этим

Тогда дико извиняюсь за необоснованный наезд
Не стреляйте в пианиста, он играет как умеет...
Re[3]: Возвращение массива из функции
От: Alex Smirnov Россия  
Дата: 29.07.02 12:55
Оценка:
Здравствуйте m.a.g., Вы писали:

...>Здравствуйте PSP, Вы писали:


PSP>>корректно будет так:


PSP>>
PSP>>void f(sA* & pSA, int &count)
PSP>>{
PSP>>  sA *pRes = new sA[nmbSA];
PSP>>  pSA = pRes;
PSP>>}

PSP>>main()
PSP>>{
PSP>>  f(pSA, nmbSA);
PSP>>  if(pSA)
PSP>>    delete pSA;
PSP>>}

PSP>>


...>То ли я туплю? Все делают одну и ту же ошибку. Удалять надо так:

...>
...>delete [] pSA;
...>


...>m.a.g. — Ты единственный умный человек в этой толпе!!!

и чем народ не устраивает просто sA* p=(sA*)new sA[count];
Alex
Re[4]: Возвращение массива из функции
От: santucco  
Дата: 29.07.02 13:11
Оценка:
Здравствуйте Alex Smirnov, Вы писали:

AS>Здравствуйте m.a.g., Вы писали:


...>>Здравствуйте PSP, Вы писали:


PSP>>>корректно будет так:


PSP>>>
PSP>>>void f(sA* & pSA, int &count)
PSP>>>{
PSP>>>  sA *pRes = new sA[nmbSA];
PSP>>>  pSA = pRes;
PSP>>>}

PSP>>>main()
PSP>>>{
PSP>>>  f(pSA, nmbSA);
PSP>>>  if(pSA)
PSP>>>    delete pSA;
PSP>>>}

PSP>>>


...>>То ли я туплю? Все делают одну и ту же ошибку. Удалять надо так:

...>>
...>>delete [] pSA;
...>>


...>>m.a.g. — Ты единственный умный человек в этой толпе!!!

AS> и чем народ не устраивает просто sA* p=(sA*)new sA[count];
Я дико извиняюсь за собственную тупость — но я не понял сокровенного смысла этой конструкции
Не стреляйте в пианиста, он играет как умеет...
Re[5]: Возвращение массива из функции
От: Alex Smirnov Россия  
Дата: 29.07.02 13:38
Оценка:
Здравствуйте santucco, Вы писали:

S>Здравствуйте Alex Smirnov, Вы писали:


AS>>Здравствуйте m.a.g., Вы писали:


...>>>Здравствуйте PSP, Вы писали:


PSP>>>>корректно будет так:


PSP>>>>
PSP>>>>void f(sA* & pSA, int &count)
PSP>>>>{
PSP>>>>  sA *pRes = new sA[nmbSA];
PSP>>>>  pSA = pRes;
PSP>>>>}

PSP>>>>main()
PSP>>>>{
PSP>>>>  f(pSA, nmbSA);
PSP>>>>  if(pSA)
PSP>>>>    delete pSA;
PSP>>>>}

PSP>>>>


...>>>То ли я туплю? Все делают одну и ту же ошибку. Удалять надо так:

...>>>
...>>>delete [] pSA;
...>>>


...>>>m.a.g. — Ты единственный умный человек в этой толпе!!!

AS>> и чем народ не устраивает просто sA* p=(sA*)new sA[count];
S>Я дико извиняюсь за собственную тупость — но я не понял сокровенного смысла этой конструкции

На то он и сокровенный!

Зачем нужно придумывать функцию простого выделения памяти
чтоб потом на продолжении долгого времени успешно искать ошибку
Alex
Re[6]: Возвращение массива из функции
От: santucco  
Дата: 29.07.02 13:54
Оценка:
Здравствуйте Alex Smirnov, Вы писали:

AS>Здравствуйте santucco, Вы писали:


S>>Здравствуйте Alex Smirnov, Вы писали:


AS>>> и чем народ не устраивает просто sA* p=(sA*)new sA[count];

S>>Я дико извиняюсь за собственную тупость — но я не понял сокровенного смысла этой конструкции

AS> На то он и сокровенный!


AS>Зачем нужно придумывать функцию простого выделения памяти

AS>чтоб потом на продолжении долгого времени успешно искать ошибку
Ну, new [] — это не простое выделение памяти, а выделение памяти под массив элементов с вызовом конструктора по умолчанию для каждого элемента массива.
delete [] соответственно вызовет деструктор для каждого элемента массива и освободит выделенную память.
Я сокровенность преобразования sA* к sA* я все-таки не понял .
Если это попытка ВНЕШНЕ (то есть для успокоения зрения )привести указатель на память под массив элементов к указателю на память под элемент, то попытка эта не только наивная, но и опасная с точки зрения утечек памяти.
И она вовсе не дает право освобождать память, выделенную new [], с помощью delete.
Не стреляйте в пианиста, он играет как умеет...
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.