Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/25: Рейтинг темы: голосов - 25, средняя оценка - 4.92
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
1

Добавить значение в конец динамического массива (имитация функции вектора)

09.12.2012, 11:20. Показов 4892. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
C++
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
 
using namespace std;
 
void show(int **P,int N)  //отображение массива
{
  for (int i=0;i<N;i++) cout<<(*P)[i]<<"  ";
  cout<<endl;
}
 
void create(int **P,int N) //создание массива
{
    *P=new int[N]; //выделяю память
    for (int i=0;i<N;i++) (*P)[i]=i+1; //Заполняю   
}
 
/*ВОТ ТУТ НЕ ЗНАЮ КАК*/
void add(int**P,int &N,int x) //добавляю один элемент в конец массива
{
  N++; //увеличиваю диапазон значений на один
  int *temp=new int[N]; //временный указатель
  temp=*P; 
  temp[N-1]=x;
  show(&temp,N); //вызывает ошибку
  *P=temp;
}
 
int main()
{
    int *P; //Указатель будет использован как массив
    int N=0; //число элементов в массиве
    cin>>N; 
    ////////////////
 
    create(&P,N); //создание массива с выделением памяти
    show(&P,N); //отображаю массив на экране
    add(&P,N,100); //попытка выделить ячейку памяти в конец массива и поместить туда 100, не затирая остального
 
    delete []P; //освобождение памяти
        
    return 0;
}
Интересует функция add для добавления только одного элемента в конец динамического массива. В коде она не сделана совсем, потому что не знаю почему ошибка и как исправить.
Интересует правильное освобождение памяти при подобном программировании. Возможно я освобождаю не так. Т.е. интересует как правильно освобождать, если выделялась в функциях. Например если я внутри отдельной функции выделю новую ячейку памяти в конец массива, запишу туда элемент, то как правильно освобождать потом. Интуитивно понимаю, что именно этот новый элемент не удалится, если использовать освобождение так как прописано у меня.

Не интересует vector, интересует велосипед.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.12.2012, 11:20
Ответы с готовыми решениями:

Добавить в конец динамического массива новый элемент
class Program { static void Main(string args) { int size = 5; ...

Как добавить в конец двумерного динамического массива строку?
Уже какой день долблюсь и не могу добавить в конец динамического массива строку. Суть задания...

Функция: посчитать сумму элементов динамического массива, перераспределить память и добавить сумму в конец
функция считает сумму элементов массива, перераспределяет память и добавляет сумму в конец, при...

Если в массиве присутствует заданное значение - удалить его, иначе добавить в конец массива
Определить, есть ли в целочисленном массиве Q(10) заданное число Х, и если есть, то удалить его...

19
ComfyMobile
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 11:46 2
C++
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
 
using namespace std;
 
void show(int **P,int N)  //отображение массива
{
  for (int i=0;i<N;i++) cout<<(*P)[i]<<"  ";
  cout<<endl;
}
 
void create(int **P,int N) //создание массива
{
    *P=new int[N]; //выделяю память
    for (int i=0;i<N;i++) (*P)[i]=i+1; //Заполняю
}
 
/*ВОТ ТУТ НЕ ЗНАЮ КАК*/
void add(int**P,int &N,int x) //добавляю один элемент в конец массива
{
  N++; //увеличиваю диапазон значений на один
  int *temp=new int[N]; //временный указатель
  for (int i = 0; i < N-1; i++) {
     temp[i]=(*P)[i];            // у вас было  temp=*P; что озночало что выделенная
  }                             // память на tmp  утекала так как его адрес терялся
  temp[N-1]=x;
  show(&temp,N); //вызывает ошибку
  *P=temp;
  delete temp;
}
 
int main()
{
    int *P; //Указатель будет использован как массив
    int N=0; //число элементов в массиве
    cin>>N;
    ////////////////
 
    create(&P,N); //создание массива с выделением памяти
    show(&P,N); //отображаю массив на экране
    add(&P,N,100); //попытка выделить ячейку памяти в конец массива и поместить туда 100, не затирая остального
 
    delete []P; //освобождение памяти
 
    return 0;
}
Миниатюры
Добавить значение в конец динамического массива (имитация функции вектора)  
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
09.12.2012, 11:57  [ТС] 3
Может и работает иногда, но в коде есть ошибка. В вашем, Nixy
Миниатюры
Добавить значение в конец динамического массива (имитация функции вектора)  
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
09.12.2012, 12:02  [ТС] 4
память на tmp утекала так как его адрес терялся
Как же он терялся, если я его носом тыкал на начало другой кучи?)
0
ComfyMobile
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 12:07 5
Цитата Сообщение от daslex Посмотреть сообщение
Как же он терялся, если я его носом тыкал на начало другой кучи?)
а так что темп это адрес скажем 00000 вы выделили под него 5 адресов типа инт каждый по 4 байта последний эллемент бужет 00020, а потом вы делаете как вы говорите тыкание носом, скажем в адрес 00024, это начало массива адресов P, и каким таким образом темп будет помнить о том что его то значения 00000-00020? никаким в этом то и ошибка, фактически у вас стало два массива P старого размера, насчет ошибки, у меня все работает, возможно это ошибки дебага, запускайте без дебага
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
09.12.2012, 12:09  [ТС] 6
Как там терялась понял, но все равно ошибка осталась.
0
ComfyMobile
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 12:10 7
Цитата Сообщение от daslex Посмотреть сообщение
Как там терялась понял, но все равно ошибка осталась.
вы в дебаг режиме запускаете? по пробуйте просто ран
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
09.12.2012, 13:14  [ТС] 8
Ctrl+F5 запускаю.

=============
Там еще одна утечка. Может из-за нее? P утекает. еще не исправил я, может поможет

Добавлено через 4 минуты
не помогло. ошибка

Добавлено через 16 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void add(int**P,int &N,int x) //добавляю один элемент в конец массива
{
  N++; //увеличиваю диапазон значений на один
  int *temp=new int[N+1]; //временный указатель
  int *temp2;
 
  for (int i = 0; i < N; i++)  temp[i]=(*P)[i]; //копирую данные из кучи *P в кучу temp
  temp[N-1]=x; //Дописываю элемент
  show(&temp,N); //вызывает ошибку
 
  //тут проблема!!!
  for (int i = 0; i < N; i++) (*P)[i]=temp[i]; //копирую обратно. 
  *P=temp; //К P не было добавлено выделенной ячейки памяти
  delete temp;
}
так всё как-то не так. Память должна добавиться, но она не будет добавлена. Как быть?

Добавлено через 22 минуты
C++
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <iostream>
 
using namespace std;
 
void show(int **P,int N)  //отображение массива
{
  for (int i=0;i<N;i++) cout<<(*P)[i]<<"  ";
  cout<<endl;
}
 
void create(int **P,int N) //создание массива
{
    *P=new int[N]; //выделяю память
    for (int i=0;i<N;i++) (*P)[i]=i+1; //Заполняю
}
 
/*ВОТ ТУТ НЕ ЗНАЮ КАК*/
void add(int**P,int &N,int x) //добавляю один элемент в конец массива
{
    N++;
 
    P[N]=new int[sizeof(N)]; //выделяю память для новой ячейки
    (*P)[N-1]=x;    //записываю значение
}
 
int main()
{
    int *P; //Указатель будет использован как массив
    int N=0; //число элементов в массиве
    cin>>N;
    ////////////////
 
    create(&P,N); //создание массива с выделением памяти
    show(&P,N); //отображаю массив на экране
    add(&P,N,100); //попытка выделить ячейку памяти в конец массива и поместить туда 100, не затирая остального
    show(&P,N);
    add(&P,N,200);
    show(&P,N);
 
    return 0;
}
Исправил. при первом добавлении всё норм, а при втором ошибка.
Вопрос с освобождением памяти остался

Добавлено через 14 минут
До 50 теперь норм, дальше ошибка
C++
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
 
using namespace std;
 
void show(int **P,int N)  //отображение массива
{
  for (int i=0;i<N;i++) cout<<(*P)[i]<<"  ";
  cout<<endl;
}
 
void create(int **P,int &N) //создание массива
{
    N++;
    *P=new int[N]; //выделяю память
    for (int i=0;i<N;i++) (*P)[i]=i+1; //Заполняю
    
}
 
/*ВОТ ТУТ НЕ ЗНАЮ КАК*/
void add(int**P,int &N,int x) //добавляю один элемент в конец массива
{   
    P[N]=new int[sizeof(int)];
    (*P)[N]=x;  
     N++;
}
 
int main()
{
    int *P; //Указатель будет использован как массив
    int N=0; //число элементов в массиве
    cin>>N;
    ////////////////
 
    create(&P,N); //создание массива с выделением памяти
   
    
    /*Запись в конец по одному значению циклом*/
    show(&P,N);
    for (int i=0;i<40;i++)
    {
      add(&P,N,i+i);
      show(&P,N);
 
    }
    
    
    return 0;
}
как освобождать память теперь?
0
ComfyMobile
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 13:21 9
я не понимаю что ты мудришь? мой код замечательно работает
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void add(int**P,int &N,int x) //добавляю один элемент в конец массива
{
  N++; //увеличиваю диапазон значений на один
  int *temp=new int[N+1]; //временный указатель
  int *temp2;
 
  for (int i = 0; i < N; i++)  temp[i]=(*P)[i]; //копирую данные из кучи *P в кучу temp
  temp[N-1]=x; //Дописываю элемент
  show(&temp,N); //вызывает ошибку
 
  //тут проблема!!!
  for (int i = 0; i < N; i++) (*P)[i]=temp[i]; //копирую обратно. 
  *P=temp; //К P не было добавлено выделенной ячейки памяти
             // а P и не надо оно после этой строки указвает на другое место в памяти, можно перед этим убить
            // предыдущий указатель P
  delete temp;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
void add(int**P,int &N,int x) //добавляю один элемент в конец массива
{
  N++; //увеличиваю диапазон значений на один
  int *temp=new int[N]; //временный указатель
  for (int i = 0; i < N-1; i++) {
     temp[i]=(*P)[i];
  }
  temp[N-1]=x;
  delete P;    // освободим Р
  show(&temp,N);
  *P=temp;      // P указывает на облось tmp
  delete temp;  // убиваем tmp
}
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
09.12.2012, 14:32  [ТС] 10
Цитата Сообщение от Nixy Посмотреть сообщение
мой код замечательно работает
В main
C++
1
2
3
4
/*Запись в конец по одному значению циклом*/
    show(&P,N); 
      add(&P,N,5);
      show(&P,N);
неверно

Добавлено через 7 минут
В обоих случаях неверно
1. Не то выводит
2. Ошибка.
==============
поэтому мудрю.

Добавлено через 51 минуту
Цитата Сообщение от Nixy Посмотреть сообщение
delete P; // освободим Р
неправильно освобождаете кучу (мало ли кто-то прочтет, возьмет в привычку и потом будет страдать)
0
ComfyMobile
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 14:35 11
если убрать delete P , то будет работать вот так
Код
C++
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
28
29
void add(int**P,int &N,int x) //добавляю один элемент в конец массива
{
  N++; //увеличиваю диапазон значений на один
  int *temp=new int[N]; //временный указатель
  for (int i = 0; i < N-1; i++) {
     temp[i]=(*P)[i];
  }
  temp[N-1]=x;
  show(&temp,N);
  *P=temp;      // P указывает на облось tmp
  delete temp;  // убиваем tmp
}
 
int main()
{
    int *P; //Указатель будет использован как массив
    int N=0; //число элементов в массиве
    cin>>N;
    ////////////////
 
    create(&P,N); //создание массива с выделением памяти
    for (int i = 0; i < 10; i++) {
     add(&P,N,i*100);
    }
 
    delete []P; //освобождение памяти
 
    return 0;
}
Миниатюры
Добавить значение в конец динамического массива (имитация функции вектора)  
0
670 / 198 / 29
Регистрация: 10.05.2012
Сообщений: 595
09.12.2012, 14:39 12
daslex, Дам простой совет, сразу приношу извинения, если вам это известно (я не читал все сообщения). Вектор - класс, содержащий динамический массив, в котором есть capacity - это реальная длина дин. массива, а size - его формальная длина, и если size >= capacity вектор создаёт новый дин. массив длины capacity * 2 и помещает в начало старый вектор

Добавлено через 59 секунд
daslex, и ещё, у вас вообще нету ооп, а только функционал, попробуйте написать класс vector
1
ComfyMobile
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 14:41 13
Цитата Сообщение от Ternsip Посмотреть сообщение
daslex, Дам простой совет, сразу приношу извинения, если вам это известно (я не читал все сообщения). Вектор - класс, содержащий динамический массив, в котором есть capacity - это реальная длина дин. массива, а size - его формальная длина, и если size >= capacity вектор создаёт новый дин. массив длины capacity * 2 и помещает в начало старый вектор

Добавлено через 59 секунд
daslex, и ещё у вас вообще нету ооп, а только функционал, попробуйте написать класс vector
тут все в сообщении есть, проблема стоит в правильном освобождении памяти
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
09.12.2012, 15:05  [ТС] 14
Цитата Сообщение от Nixy Посмотреть сообщение
если убрать delete P , то будет работать вот так
Тут как бы с одной стороны мелочь
delete P; //Это как голову отрубили, а остальное всё как Ленин в Мавзолее
delete []P; //Это удаление массива

я об этом.
===============
Вот, что у меня с вашим последним кодом
Миниатюры
Добавить значение в конец динамического массива (имитация функции вектора)  
0
ComfyMobile
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 15:29 15
ужас какой, возможно дело в том что делаем delete tmp, мой компилятор мусором не забрасывает ,а у вас бросает, получается delete P можем оставить но вот после строки *P=tmp tmp удалять нельзя так как получается что мы удалим и все содержимое P. мойже компилятор наоборот ругался на удаление Р а тмп удалять разрешает
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
09.12.2012, 15:37  [ТС] 16
У меня Visual Studio 2005
У вас очевидно новее, поэтому каким-то макаром может исправлять возникающий недочет.

Но, думаю, согласитесь, что сменить компилятор не выход. Если есть проблема, лучше понять почему она возникает.
Надеюсь выход найдется. В любом случае решение есть и наверняка оно до безобразия просто.
0
ComfyMobile
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 15:42 17
у меня совсем не VS ,да вы правы я сам плохо понимаю освобождение памяти, сижу разбираюсь)
0
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
09.12.2012, 17:40  [ТС] 18
Решил)))
Но почему так выходило не понял всё равно


C++
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
using namespace std;
 
void show(int **P,int &N)  //Показываю
{
 for (int i=0;i<N-1;i++) cout<<(*P)[i]<<"  ";
 cout<<endl;
}
 
 
void create(int **P, int &N) //Создаю
{
 *P=new int[N]; // Выделяю память
 for (int i=0;i<N;i++) (*P)[i]=i+1;// Заполняю по порядку
}
 
void Add(int **P,int &N, int x) //Добавляю одно значение в конец массива
{ 
  int *temp=new int[N]; //Выделяю новую память
  for (int i=0;i<N;i++) temp[i]=(*P)[i]; //Записываю туда данные
  delete [](*P); //вот так освобождаю массив, принятый функцией
 
  *P=new int[N+1]; //Выделяю для массива, принятой функцией новую память
  for (int i=0;i<N;i++) (*P)[i]=temp[i];//Записываю в массив значения из временного массива
  (*P)[N-1]=x; //Записываю новое значение в самый конец
 N++; //Увеличиваю число элементов
delete []temp; //освобождаю память от временного массива
}
 
 
void main()
{
 
 int *P=NULL;
 int N=0;
 cin>>N;
 
 
 create(&P,N); //Создал
 show(&P,N); //Показал исходный
 
 for (int i=0;i<100;i++) //Тест добавлений с помощью цикла
 {
 Add(&P,N,i+2); //Добавил один элемент
 show(&P,N); //Показал результат
 }
 delete []P; //Освободил память
 
}
Nixy, В принципе это ваш подход, только код мой. Спасибо за помощь. Интересно, будет ли работать в вашем компиляторе, а-то кто знает. Может обратная ситуация возникает.

Хотелось бы увидеть код попроще.
0
ComfyMobile
401 / 282 / 34
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 17:51 19
работает и у меня, вся суть в этих строках
C++
1
2
3
delete [](*P); //вот так освобождаю массив, принятый функцией
 
  *P=new int[N+1]; //Выделяю для массива, принятой функцией новую память
как вы к ним пришли? озаренее свыше ,или кто подсказал?
даже не в 2 а в одной имено вот в 1 , если правильно удалять Р
C++
1
2
3
4
5
6
7
8
9
10
11
12
void add(int**P,int &N,int x)
{
  N++;
  int *temp=new int[N];
  for (int i = 0; i < N-1; i++) {
     temp[i]=(*P)[i];
  }
  temp[N-1]=x;
  show(&temp,N);
  delete [](*P);
  *P=temp;
}
вот так тоже работает и меньше промежуточных действий
1
1373 / 596 / 199
Регистрация: 02.08.2011
Сообщений: 2,882
09.12.2012, 18:23  [ТС] 20
Может кто не поверит - сам.
Маленький опыт есть. Делал блог (там теория C++ 3.1 dos) -пока блог делал, получил чуть-чуть знаний. Дальше методом проб миллиона догадок удалось подобрать))

Добавлено через 25 минут
Цитата Сообщение от Nixy Посмотреть сообщение
вот так тоже работает и меньше промежуточных действий
Что-то мне кажется, что так неправильно и высокая вероятность сбоя.
0
09.12.2012, 18:23
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.12.2012, 18:23
Помогаю со студенческими работами здесь

Добавление элемента в конец динамического массива
Не понимаю почему у меня не выходит данный код (еще только учусь) void pushBack(int* arr, int*...

Добавление элемента в конец динамического массива!
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;malloc.h&gt; using namespace std; int main()...

Как в конец вектора положить случайное значение?
Подскажите, как в конец вектора положить случайное значение? Ниже мой вариант, ошибка в скрине....

Как вызвать метод вектора из динамического массива?
vector&lt;some_type&gt; *t=new vector&lt;int&gt; ; как вызвать метод из структуры\класса some_type? как...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru