Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 14, средняя оценка - 4.86
daslex
1271 / 516 / 106
Регистрация: 02.08.2011
Сообщений: 2,666
#1

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

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

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, интересует велосипед.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.12.2012, 11:20
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Добавить значение в конец динамического массива (имитация функции вектора) (C++):

Функция: посчитать сумму элементов динамического массива, перераспределить память и добавить сумму в конец - C++
функция считает сумму элементов массива, перераспределяет память и добавляет сумму в конец, при перераспределении памяти (realloc) возможно...

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

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

В конец массива b добавить максимальные элементы всех строк массива a - C++
Дано задание: Ввести двухмерный массив a и одномерный массив b. В конец массива b добавить максимальные элементы всех строк массива a. ...

Добавить элементы в начало динамического массива - C++
Доброго дня,мне нужна помощь с задачей по динамичным массивам. Суть задания:для начала нужно сформировать динамичный массив и заполнить...

Добавить в конец массива элементы, расположенные между min и max элементами исходного массива, исключая нули - C++
добавить в конец массива элементы, расположенные между минимальными и максимальными элементами исходного массива, исключая нулевые

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Nixy
ComfyMobile
400 / 281 / 8
Регистрация: 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;
}
Миниатюры
Добавить значение в конец динамического массива (имитация функции вектора)  
daslex
1271 / 516 / 106
Регистрация: 02.08.2011
Сообщений: 2,666
09.12.2012, 11:57  [ТС] #3
Может и работает иногда, но в коде есть ошибка. В вашем, Nixy
Миниатюры
Добавить значение в конец динамического массива (имитация функции вектора)  
daslex
1271 / 516 / 106
Регистрация: 02.08.2011
Сообщений: 2,666
09.12.2012, 12:02  [ТС] #4
память на tmp утекала так как его адрес терялся
Как же он терялся, если я его носом тыкал на начало другой кучи?)
Nixy
ComfyMobile
400 / 281 / 8
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 12:07 #5
Цитата Сообщение от daslex Посмотреть сообщение
Как же он терялся, если я его носом тыкал на начало другой кучи?)
а так что темп это адрес скажем 00000 вы выделили под него 5 адресов типа инт каждый по 4 байта последний эллемент бужет 00020, а потом вы делаете как вы говорите тыкание носом, скажем в адрес 00024, это начало массива адресов P, и каким таким образом темп будет помнить о том что его то значения 00000-00020? никаким в этом то и ошибка, фактически у вас стало два массива P старого размера, насчет ошибки, у меня все работает, возможно это ошибки дебага, запускайте без дебага
daslex
1271 / 516 / 106
Регистрация: 02.08.2011
Сообщений: 2,666
09.12.2012, 12:09  [ТС] #6
Как там терялась понял, но все равно ошибка осталась.
Nixy
ComfyMobile
400 / 281 / 8
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 12:10 #7
Цитата Сообщение от daslex Посмотреть сообщение
Как там терялась понял, но все равно ошибка осталась.
вы в дебаг режиме запускаете? по пробуйте просто ран
daslex
1271 / 516 / 106
Регистрация: 02.08.2011
Сообщений: 2,666
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;
}
как освобождать память теперь?
Nixy
ComfyMobile
400 / 281 / 8
Регистрация: 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
}
daslex
1271 / 516 / 106
Регистрация: 02.08.2011
Сообщений: 2,666
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; // освободим Р
неправильно освобождаете кучу (мало ли кто-то прочтет, возьмет в привычку и потом будет страдать)
Nixy
ComfyMobile
400 / 281 / 8
Регистрация: 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;
}
Миниатюры
Добавить значение в конец динамического массива (имитация функции вектора)  
Ternsip
660 / 188 / 6
Регистрация: 10.05.2012
Сообщений: 595
09.12.2012, 14:39 #12
daslex, Дам простой совет, сразу приношу извинения, если вам это известно (я не читал все сообщения). Вектор - класс, содержащий динамический массив, в котором есть capacity - это реальная длина дин. массива, а size - его формальная длина, и если size >= capacity вектор создаёт новый дин. массив длины capacity * 2 и помещает в начало старый вектор

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

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

я об этом.
===============
Вот, что у меня с вашим последним кодом
Миниатюры
Добавить значение в конец динамического массива (имитация функции вектора)  
Nixy
ComfyMobile
400 / 281 / 8
Регистрация: 24.07.2012
Сообщений: 916
09.12.2012, 15:29 #15
ужас какой, возможно дело в том что делаем delete tmp, мой компилятор мусором не забрасывает ,а у вас бросает, получается delete P можем оставить но вот после строки *P=tmp tmp удалять нельзя так как получается что мы удалим и все содержимое P. мойже компилятор наоборот ругался на удаление Р а тмп удалять разрешает
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
09.12.2012, 15:29
Привет! Вот еще темы с ответами:

Добавить строку в конец массива - C++
как добавить строку в конец массива string str (без использования list, векторов) ?

Добавить указанное количество элементов в голову динамического массива - C++
Описать массив указанного пользователем количества элементов. Добавить указанное количество элементов в голову массива. ...

Почему при создании динамического массива через new ячейки массива имеют значение -842150451? - C++
Я хотел бы узнать почему при создании динамического массива через операцию new ячейки массива имеют значение -842150451. #include...

Как прочесть несколько слов из файла в динамический массив char и добавить новое значение в конец? - C++
Никак не могу разобраться. Есть текстовый файл в виде: 3 Mop floor Clean windows Mow lawn цифра 3 это количесво...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
09.12.2012, 15:29
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru