Задача на динамическое выделение памяти. Изначально есть указатель на массив с одним элементом. Пользователь вводит число. Если оно больше 0 записываем его в массив. Далее пользователь вводит второе число, тут уже, если оно больше 0, надо пере выделять память для 2-х элементов массива и записать в массив второе число. И так далее… для 3-х элементов, для 4-х… пока пользователь не введет отрицательное число.
Пример работы программы:
Исходный код программы показан ниже:
#include <iostream>
using namespace std;
int main()
{
setlocale(LC_ALL, "rus");
int *p = new int[1];
int *p2;//для копирования данных из массива p перед удалением памяти
int a = 0;//число, которое вводит пользователь
int nSize = 0;//размер динамического массива, который будет увеличиваться на 1, при вводе положительного числа
while(a >= 0){
cout << "\nВведите целое число: ";
cin >> a;
if(a < 0){
break;//если введено отрицательное число - break
}
if(nSize == 0)
{
p[nSize] = a;
cout << p[nSize];
nSize++;//1
}
else
{
p2 = new int [nSize + 1];
for(int i = 0; i < nSize; i++)
{
p2[i] = p[i];//скопировали массив
}
p2[nSize] = a;
delete [] p; //чистим память
p = new int[nSize + 1]; //выделяем новую память
for(int i = 0; i < (nSize+1); i++)
{
p[i] = p2[i]; //копируем данные из временного массива
cout << p[i] << " ";//и отображаем все его элементы на экран
}
delete [] p2;//чистим память временного массива
nSize++;//увеличиваем на 1
}
}
delete [] p;//чистим память перед завершением программы
return 0;
}
Смотрим результат работы программы:
CppStudio.com
Введите целое число: 3 3 Введите целое число: 4 3 4 Введите целое число: 5 3 4 5 Введите целое число: 6 3 4 5 6 Введите целое число: 7 3 4 5 6 7 Введите целое число: 8 3 4 5 6 7 8 Введите целое число: 5 3 4 5 6 7 8 5 Введите целое число: 4 3 4 5 6 7 8 5 4 Введите целое число: 0 3 4 5 6 7 8 5 4 0 Введите целое число: 0 3 4 5 6 7 8 5 4 0 0 Введите целое число: 7 3 4 5 6 7 8 5 4 0 0 7 Введите целое число: -1
Комментарии
Lee Amstrong
Вот. Запилил без копирования памяти (за некоторыми оговорками). Кратко опишу как работает. Выделяем кусок памяти n-байт, столько, что бы хватило для одного числа. При записи, проверяем, если наш кусочек заполнен, то выделяем еще.
В чем отличие от метода, который приведен в решении. Там, если закончилось место, то выделяется новый массив, а старый копируется туда, что как бы некоторые накладные расходы. В моем же методе, если место закончилось то к уже выделенному кусочку довыделяется еще память (по типу откусывания кусочков от палки).
Оговорка заключается в том, что если за нашей памятью память, используемая кем-то другим, или даже другим элементом нашей программы (скажем там, палку откусил кто-то другой), то идет все таки копирование в новую область памяти, но это уже забота ОС.
#include <iostream> #include <cstdlib> #include <assert.h> #include <limits> int main(int argc, char const *argv[]) { //выделяем память для 1-го инта void* memory = malloc(sizeof(int)); assert(memory); //Кидаем исколючение если не удалось выделить память size_t capacity = 1; //вместительность выделенного кусочка памяти size_t elements = 0; //Количество элементов на нашем кусочке while (true) { int num; std::cout << "Введите число: "; std::cin >> num; //сработает, если мы попытаемся ввести буквы, вместо числа, или число которое не поместится в int if (std::cin.fail()) { std::cout << "Шота сломалось :(" << '\n'; break; } if (num < 0) { break; } if (capacity == elements) { capacity++; //Временный указатель, по предупреждению анализатора pvs-Studio: // V701 realloc() possible leak: when realloc() fails in allocating memory, //original pointer 'memory' is lost. Consider assigning realloc() to a temporary pointer. void* tempPtr = realloc(memory, sizeof(int)*capacity); //++capasity вначале увеличит свое значение, а потом уже пойдет в функцию assert(tempPtr); //То же, что и 1й ассерт memory = tempPtr; } //Приводим к типу int, для дальнейшей записи в него числа int* int_memory = reinterpret_cast<int*>(memory); int_memory[elements] = num; elements++; std::cout << "Записанные числа: "; for (size_t i = 0; i < elements; i++) { std::cout << int_memory[i] << " "; } std::cout << '\n'; std::cout << "Кусочек памяти занимает: " << sizeof(int) * capacity << " байт\n"; } //Освобождаем память free(memory); return 0; }А еще я так и не понял как пофиксить предупреждение статического анализатора, но вроде все работает:
Alexander Trousevich
// Language: rust. Details: rust-lang.org use std::io; fn read_integer() -> u32 { let mut buf: String = String::new(); io::stdin().read_line(&mut buf).expect("Invalid Input"); buf.trim().parse().expect("Not a number") } fn main() { let mut ans: Vec<u32> = Vec::new(); loop { let n = read_integer(); match n { 0 => break, _ => ans.push(n) } } for i in ans { println!("{}", i) } }Alex Pir
Ребят помогите плиз у меня проблема из чисткой памяти, вот код (Не судите строго ,я только начинающий Вот код):
#include <iostream> using namespace std; int main() { int size = 1; int *arr = new int[size] {}; int *arr2 = new int[size + 1]; int a; cin >> a; for (int l = 0; a >= 0; l++) { cout << "Enter value: "; cin >> a; cout << "Array: "; for (int i = 0; i < size + l; i++) { arr2[i] = arr[i]; arr2[l] = a; arr[i] = arr2[i]; cout << arr2[i] << "\t"; } cout << endl; } }Dentchik 2016(Just Do it)
Просто и доступно , просто если бы обявили
#include<bits/stdc++.h> using namespace std; int main() { int* arr = new int[1]; int cur , raz = 0; do { cin >> cur; if(cur >= 0) { arr[raz] = cur; raz++; } }while(cur >= 0); for(int i = 0;i < raz;i++) cout << arr[i] << " "; delete [] arr; }Gosha
Многие тут допускают одну и туже ошибку.
Динамическая память не означает, что она резиновая. Сколько выделили через new, таким размером и можно пользоваться.
За границами выделенных адресов под массив, могут находится другие данные, при затирании которых, программа перестанет работать.
Просто такая программа слишком примитивна и в ней мало данных, поэтому эта проблема не проявляется, и кажется что программа работает корректно.
Чтобы увеличить динамический массив на один элемент его нужно удалить, а потом выделить заново память на один элемент больше.
Естественно перед удалением данные надо куда-то сохранить, а это приводит к необходимости завести еще один динамический буферный массив, в этом и есть смысл задачи.
Т.е. те у кого один динамический массив сразу уже не в теме.
Eduard_P
Решение несложное, комментарии писались дольше чем сам код.
Заняло 30мин.
#include <cstdlib> #include <iostream> using namespace std; /* * */ int main(int argc, char** argv) { int*array;//основной массив int*array1;//вспомогательный массив int n=1, i, j; for(i=0; i<n; i++){ //основной цикл array = new int[n];//декларация основного массива for(j=0; j<n; j++) {*(array+j)=*(array1+j);}//копирование данных с воспом. в основнай if(i>0){delete array1;}//удаление вспомогательного массива начиная со второг цикла array1 = new int[n];//декларация вспомогательного массива cout << "Введите целое число: ";//вывод на экран запроса cin >> *(array+i);//ввод пользователем данных if (*(array+i)>=0){//остановка вывода массива при отрицательном вводе for (j=0; j<n; j++){ cout << *(array+j) << " ";}//вывод данных основного массива } cout << "\n";//перевод строки if (*(array+i)>=0) n++;//прибавление цикла в случае положит числа for(j=0; j<n; j++) {*(array1+j)=*(array+j);}//копирование данных с основного в воспомог. массив delete array;//удаление основного массива } delete array1; return 0; }fishb0ne
#include <iostream> #include <cstdlib> int main() { int *vect = (int *) malloc(1), num, count = 0; do { count++; std::cout<<"\nВведите целое число: "; std::cin>>num; if (num > 0) { realloc(vect,count * sizeof(int)); vect[count-1] = num; } else count--; for (int i = 0; i < count; i++) std::cout<<vect[i] << " "; } while (num >= 0); free(vect); return 0; }