powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Выделение памяти в функции
23 сообщений из 23, страница 1 из 1
Выделение памяти в функции
    #34441467
Yurman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как правильно выделить память под массив в функции. Пока делаю так, но это не правильно конечно.

void InitArray(int *mas)
{
delete mas;
mas= new int[10];
for (int i=0;i<10;i++)
{
mas =i;
}
};

void main()
{
int *MainMas;
MainMas= new int;
InitArray(MainMas);

for (int i=0;i<10;i++)
printf("%d",MainMas);

delete MainMas;
};
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34441492
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YurmanКак правильно выделить память под массив в функции. Пока делаю так, но это не правильно конечно.

void InitArray(int *mas)
{
delete mas;
mas= new int[10];
for (int i=0;i<10;i++)
{
mas =i;
}
};

void main()
{
int *MainMas;
MainMas= new int;
InitArray(MainMas);

for (int i=0;i<10;i++)
printf("%d",MainMas);

delete MainMas;
};


Передавай по ссылке
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34441865
Yurman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Напишите как пожалуйста.
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34441880
Фотография blinded
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YurmanНапишите как пожалуйста.
Akh спать пошел, так что придется мне
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
void InitArray(int*& mas)
{
  if (mas)                                // надо проверить на 0 иначе обломается
    delete[] mas;                      // создавал массив, так и удаляй массив.
  mas= new int[ 10 ];
  for (int i= 0 ;i< 10 ;i++)
  {
    mas[i]=i;                            // присваивать значение надо элементу массива а не указателю
  }
}

void main()
{
 int* MainMas =  0 ;                   // надо бы проинициализировать 
 InitArray(MainMas);

  for (int i= 0 ;i< 10 ;i++)
    printf("%d",MainMas[i]);       // печатать наверное хотел элементы массива а не его адрес 10 раз

  delete[] MainMas;                 // опять с удаление
}
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34441906
Yurman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо.
Ради интереса, а в чем приемущество этого способа. Я думал просто указатель можно сунуть без инициализации и удаления. Или мой способ в корен неправильный?
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34442020
mikhail_n
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
От блин, развели турусы на колёсах. Если нужно передавать одномерный массив, делайте просто так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
void InitArray(int a[], int n)
{
      for (int i= 0 ;i<n;i++)
      {
           a[i] = i;
       }
};

void main()
{

int a[ 10 ];
InitArray(a,  10 );

for (int i= 0 ;i< 10 ;i++)
printf("%d",a[i]);

};

Массивы в C/C++ передаются по ссылке, не по значению, это стандарт языка.
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34442028
ErV
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
blinded
Код: plaintext
1.
2.
  if (mas)                                // надо проверить на 0 иначе обломается
    delete[] mas;                      // создавал массив, так и удаляй массив.

Зачем??? достаточно просто delete[] mas, без if. Нулевые указатели можно удалять.
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34442312
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YurmanЯ думал просто указатель можно сунуть без инициализации и удаления. Или мой способ в корен неправильный?

Можно, можно. В твоем случае, если хочешь использовать этот подход, договорись сам с собой, что в эту функцию будешь передавать ссылку на неинициализированный указатель, тогда просто в него записываешь указатель на выделенную память, ничего с ним предварительно не делая.
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34442351
grieg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1) Память должа выделяться и освобождаться на одном и том же уровне. Оба действия в main. Оба действия в InitArray, DeleteArray соответственно. Выделение/освобождение на разных уровнях приведут к непонятному коду и ошибкам. Это не я придумал.
2) Память (как и любой другой ресурс, требующий освобождения) следует выделять в конструкторах и освобождать в деструкторах. Это позволит избежать ошибок и безопасно с точки зрения исключений.
3) Память вообще не надо выделять и освобождать руками. Пользуйся std::vector.
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34444434
Yurman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дайте почитать где написано о нежелательности выделения памяти на разных уровнях.
Может там напишут как лучше сделать такие функции как загрузка текстового файла, или загрузка векторного объекта например.
Я ведь не могу до вызова функции знать сколько будет элементов. Получается надо будет вызвать функцию которая узнает сколько
будет элементов. Потом в Main проинициализировать массив. А потом вызвать функцию которая загрузит этот массив.
Может так оно и правильнее но проект уже и так большой и лишний раз перегружать его этим не хочется.
Для примера приведу функцию которая есть в скриптовом языке одного векторного редактора.
int mdlElement_stroke(DPoint3d** points,int* nPoints,MSElement* el,double tol);
DPoint3d** points это массив точек векторного объекта
int* nPoints колличество точек
заранее я не знаю колличества точек а просто передаю points в эту функцию и она сама выделяет память и возрашает кол-во точек
к сожалению ее исходников у меня нет вот и хотел спросить как это лучше реализовывается.
в том что сделал я не нравится что указатель приходится инициализировать MainMas= new int а потом в функции удалять, но работает

PS для mikhail_n иже с ними, я не передать массив хочу а память в функции выделить
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34444461
Фотография blinded
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YurmanДля примера приведу функцию которая есть в скриптовом языке одного векторного редактора.
int mdlElement_stroke(DPoint3d** points,int* nPoints,MSElement* el,double tol);
DPoint3d** points это массив точек векторного объекта
int* nPoints колличество точек
заранее я не знаю колличества точек а просто передаю points в эту функцию и она сама выделяет память и возрашает кол-во точек
к сожалению ее исходников у меня нет вот и хотел спросить как это лучше реализовывается.
в том что сделал я не нравится что указатель приходится инициализировать MainMas= new int а потом в функции удалять, но работает

PS для mikhail_n иже с ними, я не передать массив хочу а память в функции выделить
Возьмите std::vector и вас не будет волновать ни выделение.освобождение памяти, да и предавать указатель на пременную- количество точек не придется И вести себя будет как массив

int mdlElement_stroke(std::vector<DPoint3D>& points, MSElement& el,double tol);
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34444571
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yurman
в том что сделал я не нравится что указатель приходится инициализировать MainMas= new int а потом в функции удалять, но работает


в твоем случае это не нужно. я тебе это уже написал
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34444685
Yurman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хорошо, я еще почитаю в страуструпе, только конечно вс еперелопачивать придеться, а классы в качестве элементов можно использовать?
И всетаки интересно как эта функция stroke получая в качестве аргумента указатель на указатель выделяет память без лишних движений.
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34444715
Фотография blinded
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YurmanХорошо, я еще почитаю в страуструпе, только конечно вс еперелопачивать придеться, а классы в качестве элементов можно использовать?

Конечно, только не классы а объекты классов. Надо только помнить что стандартные контейнеры хранят объекты по значению, фактически если ты что-то кладешь в контейнер, то в нем хранится не то что ты положил, а его копия. Если нужно другое поведение или полиморфное поведение объектов придется хранить указатели, или еще луше ссмартпойнтеры
Yurman
И всетаки интересно как эта функция stroke получая в качестве аргумента указатель на указатель выделяет память без лишних движений.
А чего там интересного... все тривиально. Сначала аллокируем массив некоторого размера, ну скажем 64 элемента, начинаем писать в него, если места нехватает, аллокируем массив в 2 раза больше переписываем из первоначального все во второй,ну и пока не считаем из файла все. Ежели охота вернуть лишнюю память системе - снова аллокируем массив точного размера и опять переписываем. Тупо и надежно. в С даже функция такая есть realloc называется
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34444721
Yurman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Понятно, тогда скажите какие минусы того как сделал я. Потому что возникло желание оставить все как есть.
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34444761
grieg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Небольшое уточнение. Не всякие объекты можно хранить в std::vector. У них должны быть корректные конструкторы копирования, операторы присваивания, конструкторы и деструкторы. Более подробно смотри в литературе.
На практике это означает, что все нормальные объекты можно хранить.
Пример того, что нельзя: auto_ptr. Потому что после присваивания одному значение другого они не будут одинаковыми.
int mdlElement_stroke -- функция, написанная на Си. В С++ так уже не модно.
Что ты сделал неверно:
1) blinded в основном написал все по делу. Так что сначала исправь откровенные ошибки, тогда можно будет более предметно обсуждать.
2) InitArray -- я не нашел в документации описания этой функции, но судя по названию она должна инициализировать массив. Я не понял, почему она удаляет старое данные уже инициализированного массива.
3) void main()
на самом деле
int main(int, char**)
4) верни из main значение
5)
Код: plaintext
1.
2.
  for (int i= 0 ;i< 10 ;i++)
    printf("%d",MainMas[i]); 
Если где-то тут произойдет исключение (а на самом деле у тебя там наверняка не только цикл, а еще куча чего, часть из чего может и исключение кинуть, то
Код: plaintext
1.
delete[] MainMas;   
никогда не выполнится и память утечет.
6) Еще раз повторюсь, что есть правила хорошего тона, которые позволяют избегать (уменьшить вероятность) ошибок по невнимательности (забытые delete) и этими правилами стоит пользоваться. Вот и все.
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34444793
Yurman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это я написал побыстренькому как примерчик. Название функции сам придумал оно ничего не значит. А delete mas; делаю потому что сделал MainMas= new int; в main, потому что если этого не сделать компилятор проходил а link выдавал ошибку.
Тоесть

int *MainMas;
//MainMas= new int;
InitArray(MainMas);

Не работает, пишет что MainMas не инициализирован или чтото в этом роде, точно не помню.
Ну а если сработает исключение в реальном проекте эт оозначает что дальнейшая работа программы не имеет смысла.
Хотелось чтобы просто было так
int *MainMas;
InitArray(MainMas);
а в функции без delete mas;
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34444830
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YurmanНу а если сработает исключение в реальном проекте эт оозначает что дальнейшая работа программы не имеет смысла.Это не означает что надо падать. Надо сначала очистить память, потом записать в лог подобное описание где и почему произошла ошибка и только потом завершать программу.

YurmanХотелось чтобы просто было так
int *MainMas;
InitArray(MainMas);
а в функции без delete mas;Нельзя так делать. Если память выделена ее надо освободить. Обязательно.
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34445040
grieg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Автор, внимательно прочитай замечания blinded
Хотя бы потому, что не надо освобождать массив оператором delete. Надо использовать delete[].
И читай, что тебе пишет компилятор. Он тебе выдал не ошибку, а предупреждение.
В общем, то, что написано в начале, содержит очень много ошибок. А больше предмета для разговора нет.
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34445069
Yurman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ошибки в main если четсно меня не интересуют, я допустил их по невнимательности.

а надо было разобраться как сделать так
int *MainMas;
//MainMas= new int тоесть без предварительной инициализации, просто сунуть в ф-цию указатель
InitArray(MainMas);

а в функции без delete mas; - это означает что в функции InitArray без delete [] mas В НАЧАЛЕ
а потом конечно в main в конце вызвать delete [] mas.

прям как в функции int mdlElement_stroke(DPoint3d** points,int* nPoints, - правда она на C

Но ответа так и не получил.
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #34445160
Фотография blinded
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сам-то понимаешь чего хочешь?
Ну ладно на тебе так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
int initArray(int*& arr, int& sz)
{
  sz =  10 ;
  arr = new int[sz];
  for(int  1  =  0 ; i < sz; ++i)
    arr[i] = i;
  return  0 ;
}

void feeArray(int* arr)
{
  delete [] arr;
}

int main()
{
 int* MainMas;
 int size;
 
 if (InitArray(MainMas, size))
   return  1 ;

 for (int i= 0 ; i<size ;i++)
    printf("%d",MainMas[i]);       // печатать наверное хотел элементы массива а не его адрес 10 раз

  freeArr(MainMas);
}
Дедушке полегчало?
C++
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Выделение памяти в функции
    #38501051
Eugen7771
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Наткнулся на запись
Код: plaintext
1.
void InitArray(int*& mas)

и был весьма удивлён. Мне казалось, операции * и & компенсируют друг друга. Даже в голову бы не пришло, но очень выручило. Поясните, почему так? Вроде ведь указателя должно хватать, ну, как тут , например.

Заодно, использовать векторы вместо массивов это разве не большой урон производительности? Я не шибко шарю, но насколько слышал, то за каждым элементом контейнеров STL стоит не просто значение, а ещё всякие премудрости типа указателей на следующий элемент и т.п. Из жизни: делал лабу — считать текстовый файлик, составить словарь и записать его в другой файл словарь. Пробовал словарь делать массивом char'ов и двусвязным списком. Первое записалось за секунду, второе за 1,5 минуты (и то и другое делал через файловые потоки и метод write() ). Это же жуть!
...
Рейтинг: 0 / 0
Выделение памяти в функции
    #38501067
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Eugen7771Наткнулся на запись и был весьма удивлён.
Записи "int** mas" ты был бы удивлён меньше?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Выделение памяти в функции
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]