Перейти к содержимому

Как уменьшить длину массива си

  • автор:

Работа с массивами в языке Си

На этой странице относительно подробно рассказывается о статических и динамических массивах. Краткое изложение основных моментов и описание методов поиска ошибок доступны при нажатии на кнопки выше. Двумерные массивы описаны на этой странице.

Массив – это линейно упорядоченная совокупность однотипных элементов. Массив определяется типом элементов (int, double, . ) и длиной. Доступ к элементам осуществляется по индексу – порядковому номеру элемента массива. Логически первый элемент массива имеет индекс ноль. В языке Си существуют статические массивы, число элементов в которых должно быть известно в момент компиляции программы, и динамические массивы, размер которых задается в процессе выполнения программы, то есть может зависеть от входных данных. Эти два типа отличаются только методом создания массива, поэтому сначала рассмотрим статические массивы.

Статические массивы

Способы объявления статических массивов

Объявление статического массива отличается от объявления обычной переменной только указанием количества элементов массива. Например, следующее объявление означает, что именем points называется массив из 100 действительных чисел.

double points[100];

В некотором смысле можно считать, что такое объявление переменной points создает 100 переменных, которые называются points[0], points[1], . points[99]. Плюс к этому, «имена» этих переменных можно вычислять: points[1], points[0+1] или points[k-1] имеют одно значение (если k=2).

В реальных программах следует избегать явного использования числовых констант в объявлениях массива (и других частях программы). Если нам нужно объявить два массива, которые теоретически могут иметь разный размер, например,

double points[100]; int students[100];

то в дальнейшем, если возникнет необходимость увеличить один из массивов, будет сложно отличить одну константу от другой. Особенно это верно при обработке элементов массива (см. ниже). Правильным считается использование директив препроцессора для присвоения константам «говорящих» имен. Например:

#define NPOINTS 100 #define NSTUDENTS 100 . double points[NPOINTS]; int students[NSTUDENTS];

Объявление массива может быть совмещено с присвоением значений его элементам. Например,

double points[] = ;

создает массив из четырех действительных чисел с указанными значениями. Заметим, что в данном случае число элементов массива в квадратных скобках не указывается. Компилятор самостоятельно вычисляет длину по списку начальных значений. В программе можно вычислить длину такого массива, разделив его размер на размер одного элемента (пример ниже).

Работа с элементами массива

Для доступа к элементу массива достаточно знать его имя и порядковый номер элемента. В языке Си элементы массива индексируются начиная с нуля, то есть в массиве из двух элементов корректными являются индексы 0 и 1. Если массив имеет имя array, то его k -й элемент записывается как array[k] . Это выражение может использоваться как для получения значения элемента массива, так и для его изменения, если оно стоит в левой части оператора присваивания. Рассмотрим для примера следующую программу.

#define NPOINTS 100 int main() < double points[NPOINTS]; int k; points[0] = 0.1; for(k=1; k < NPOINTS; k++) < points[k] = 0.1 + points[k-1]; >return 0; >

Эта программа заполняет массив действительных чисел значениями 0, 0.1, 0.2 и так далее. Отметим, что макропеременная NPOINTS используется как при объявлении массива, так и в качестве верхней границы цикла по всем его элементам. Если размер массива нужно будет изменить, то достаточно исправить одну строчку в программе (#define).

Пример работы с массивом, который задан с начальными значениями:

int main() < double points[] = ; int k; int npoints = sizeof(points)/sizeof(points[0]); for(k=0; k < npoints; k++) < printf("points[%d] = %lf\n", k, points[k]); >return 0; > 

Типичная ошибка при работе с массивами состоит в указании неправильного индекса. Если в приведенной выше программе переменная цикла k будет пробегать значения от 0 до npoints включительно, то поведение программы, вообще говоря, может быть любым. Наиболее вероятным поведением является вывод на экран какого-то значения, но может возникнуть и критическая ошибка, которая приведет к аварийной остановке программы.

Представление массива в памяти и адресная арифметика

В памяти ЭВМ элементы массива записаны последовательно без пропусков. Имя массива является указателем на его начальный элемент (с индексом 0). Поскольку в массиве все элементы имеют одинаковый тип, то зная адрес начала массива (A), размер одного элемента (size) и индекс k можно вычислить адрес размещения k-ого элемента: A + k*size. Если требуется получить значение k-ого элемента массива, то достаточно выполнить одно умножение (k*size), одно сложение (A + k*size) и загрузить значение из памяти по только что вычисленному адресу. Таким образом, обращение к элементу массива очень эффективно и сложность этой операции не зависит от величины индекса k: получение (или изменение) значения нулевого элемента столь же эффективно, как и миллионного.

Хорошо, адрес начала массива мы знаем — это его имя, индекс нам известен, но как узнать size (размер одного элемента)? Чуть ниже мы узнаем как это сделать, но для работы с указателями на элементы массива это не требуется! В языке Си к указателям можно прибавлять целые числа. Например, если есть указатель double *a; , то значением выражения a+9 будет адрес десятого (еще раз вспомним, что массивы индексируются с нуля!) элемента массива, который начинается с адреса a . Компилятор сам понимает, что a является указателем на double и прибавляет нужное значение.

Обратной стороной последовательно хранения элементов в памяти является сложность вставки нового значения с сохранением порядка следования элементов. Например, если в массив нужно добавить новое значение по индексу 0, то чтобы «освободить» место все элементы массива придется сдвинуть на одну позицию. Ясно, что сложность этой операции зависит от длины массива. Чем больше длина, тем дольше выполняется это действие.

Передача массива в функцию

Функция может получать на вход массив. В действительности в функцию передается адрес начала массива и его длина. Прототип функции может быть оформлен либо так:

int print_array(double x[], int len);
int print_array(double *x, int len);

Эти варианты являются эквивалентными. Некоторые программисты предпочитают первый (квадратные скобки показывают, что формальный параметр функции является массивом), другие — второй (имя массива является указателем на нулевой элемент). Естественно, что функция может иметь и другие параметры, в том числе, другие массивы. Это только пример.

Рассмотрим возможную реализацию функции распечатывания массива.

#include int print_array(double x[], int len) < int k; for(k = 0; k < len; k++) < printf("x[%d] = %lf\n", k, x[k]); >return 0; >

При вызове функции в качестве аргумента нужно передавать имя массива и его длину.

int main() < double points[] = ; int npoints = sizeof(points)/sizeof(points[0]); print_array(points, npoints); return 0; >

Внимание! Если функция print_array изменит значение элемента массива x (например, в цикле будет написано x[k]=0; ), то изменятся значения и в массиве points функции main. Элементы массива при вызове функций не копируются! Функция получает на вход адрес памяти, где записаны элементы массива. Эта память «общая» для вызывающей и вызываемой функции.

Динамические массивы: malloc и free

Статические массивы имеют одно существенное ограничение: размер массива должен быть известен в момент компиляции программы. В большинстве задач размер данных становится известным только в момент выполнения программы. Например, вы написали программу для обработки списка друзей или подписчиков в социальной сети. У одного пользователя друзей мало, а у другого — очень много. Какое значение выбрать для длины массива друзей? 200? 1000? Миллион? Если константа будет очень большой, чтобы «заведомо» (посмотрите как росло число пользователей Интернет) устраивать всех пользователей, то для подавляющего числа пользователей это приведет к излишним затратам памяти. Захотите ли Вы поставить на свой телефон программу, которая при запуске займет всю его память с сообщением: «А вдруг у тебя миллион друзей. Нет? Всего 12?! Неплохо, прямо как у Oушена! А y Трампа миллион. «? [Друзей не должно и не может быть так много, но это к делу не относится.] Чтобы избежать таких ситуаций нужно уметь выделять минимально необходимое количество памяти.

  • выделение памяти под массив;
  • освобождение памяти, когда она больше не требуется.

Стандартная библиотека языка Си содержит несколько функций для работы с динамической памятью. Нам понадобятся две: malloc (memory allocation — выделение памяти) и free (освобождение). Для использования этих удивительных функций нужно в программе подключить заголовочный файл . Пример программы приведен ниже. Сначала посмотрим, что делают эти функции.

malloc: динамическое выделение памяти

Прототип: void *malloc(size_t size); Параметры: size — беззнаковое целое число, размер запрашиваемой памяти в байтах. Возвращает: Адрес начала выделенной памяти или NULL, если не удалось выделить память. Функция malloc возвращает указатель типа void * — это «абстрактный» указатель на память, который может быть приведен к указателю на любой тип. Функция malloc не может сразу возвращать указатель нужного типа, так как она используется для создания разных массивов, а в прототипе нужно указать конкретный тип возвращаемого значения.

Для выделения памяти под массив из n элементов типа T, где в T могут быть стандартные типы int , double и т.п., необходимо знать размер значения T в байтах. Для определения этой величины в языке Си есть специальный оператор sizeof , который в момент компиляции программы вычисляет нужное значение. Например, массив из n целых чисел будет занимать n*sizeof(int) байт памяти.

Таким образом, для создания динамического массива некоторого типа, например с массива целых чисел, нужно использовать команду вида:

int length; int *points; // . получили значение length (длина массива) points = (int *)malloc(length * sizeof(int));

Если нужен другой тип данных, допустим double , то int заменяется на нужное имя ( double ) в трех местах (кроме первой строки, так как длина массива всегда является целым числом).

free: освобождение памяти

Функция free позволяет освободить область памяти, которая ранее была выделена программе при вызове malloc .

Прототип void free(void *ptr); Параметры: ptr — указатель, который был получен в результат вызова malloc.

В качестве аргумента функции free может использоваться только тот адрес, который был получен в результате вызова malloc. Нельзя создать статический массив и «освободить» его функцией free. Адрес может быть освобожден только один раз. Если два раза подряд вызвать функцию free с одним и тем же аргументом, то это приведет к аварийному завершению программы.

Пример программы с динамическим массивом

В качестве иллюстрации описанных методов рассмотрим программу, которая динамически выделяет память под массив и считывает его.

#include #include int main() < int npoints; double *points; int k; scanf("%d", &npoints); /* npoints получает значение в момент выполнения программы */ points = (double *)malloc(npoints*sizeof(double)); /* Выдели память для хранения npoints элементов, каждый размера sizeof(double) */ if(points == NULL) < printf("Произошла ошибка. Запросили слишком много памяти??\n"); return -1; >/* Считываем данные с использованием адресной арифметики */ k = 0; while(k < npoints && scanf("%lf", points+k) == 1) < k++; >/* Работаем с points как с обычным массивом */ /* Например, вызываем функцию print_array(points, npoints) */ free(points); /* Освободили память */ return 0; >

Функции, которые возвращают массив

Иногда бывает удобно сделать функцию, которая возвращает динамически созданный массив. Примером может служить функция считывания массива из файла. Такая функция может получать на вход файловую переменную ( FILE * ) и должна вернуть в вызывающую функцию массив значений. Например, массив действительнах чисел. Попробуем ее реализовать.

Во-первых, нужно понять, какой прототип должна иметь такая функция. Она должна вернуть два значения: адрес выделенной памяти и длину массива. Как мы уже знаем, несколько значений можно вернуть используя указатели. Длина массива имеет тип int . Значит параметр функции будет иметь тип int * (адрес, по которому нужно записать значение). Массив — это адрес нулевого элемента, то есть double * . Значит параметр будет иметь тип double ** — «указатель на указатель». Мы должны передать адрес (одна звездочка), по которому нужно записать результат вызова malloc, который имеет тип double * . В результате получаем следующий прототип:

int read_array(FILE *input, double **array, int *length);

Собственно возвращаемое значение функции ( int ) может быть кодом ошибки. Если функция вернет 0, то это означает успешное выполнение. Любое ненулевое значение означает ошибку.

Теперь можно рассмотреть структуру тела функции (для наглядности в приведенном ниже коде отсутствуют проверки успешности считывания и корректности данных).

int read_array(FILE *input, double **array, int *length) < double *arr; int arr_length, k; /* Считываем массив: сначала длину, потом элементы */ fscanf("%d", &arr_length); arr = (double *)malloc(arr_length * sizeof(double)); for(k = 0; k < arr_length; k++) fscanf("%lf", arr + k); /* Копируем результат по заданным адресам */ *length = arr_length; *array = arr; return 0; >

Изменение размера массива

Здравствуйте. Как можно составить функцию, которая вставляет число a в начало массива (со сдвигом), изменяя
размер занимаемого массивом блока памяти? Массив динамический.

Лучшие ответы ( 1 )

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

Ответы с готовыми решениями:

Изменение размера массива
#ifndef ARRAY_H #define ARRAY_H struct array_t; typedef struct array_t Array; int.

Изменение размера массива по ходу программы
Доброго дня. Надо изменять размерность массива по ходу выполнения программы. Хотел, по.

Работа с malloc() и realloc() — динамическое изменение размера массива
Всем привет. Продолжаю свои эксперименты с динамической памятью. На этот раз хочу сделать так.

Изменение размера массива
У меня массив типа Object. Пишу так Array.Resize(ref mas, mas.Length + 2); выдает следующую.

Заблокирован

realloc
Или malloc с последующим копированием сразу со смещением. Тогда вставка вообще проста.

Заблокирован

Лучший ответ

Сообщение было отмечено maxcot как решение

Решение

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
void* resize(void *arr,void *el,int sz,int count) { if(count==1) arr=0; arr=realloc(arr,sz*count); memmove((char*)arr+sz,arr,sz*(count-1)); memmove(arr,el,sz); return arr; } int main(int argc,char* argv[]) { int i,*pi; char ch,*pc; double d,*pd; char *ps,s[][10]={"QWERTY","123456789"}; for(i=0; i10; i++) pi=resize(pi,&i,sizeof(int),i+1); for(i=0; i10; i++) printf("%d ",pi[i]); printf("\n"); for(i=0,ch='A'; ch'Z'; i++,ch++) pc=resize(pc,&ch,sizeof(char),i+1); for(ch='A'; ch'Z'; ch++) printf("%c ",pc[ch-'A']); printf("\n"); for(d=i=0; d10; i++,d++) pd=resize(pd,&d,sizeof(double),i+1); for(i=0; i10; i++) printf("%.4lf ",pd[i]); printf("\n"); for(i=0; i2; i++) ps=resize(ps,s[i],10,i+1); for(i=0; i2; i++) printf("%s\n",ps+i*10); system("pause"); free(pi); free(pc); free(pd); free(ps); return 0; }

87844 / 49110 / 22898

click fraud protection

Как только массив выделен, в языке программирования C++ нет встроенного механизма для изменения его размера. Поэтому мы можем избежать этой проблемы, динамически генерируя новый массив, копируя содержимое и затем удаляя старый массив. В этой статье основное внимание уделяется тому, как динамически выделять память в массиве и настраивать размер массива на основе пользовательского ввода. Это очень важная стратегия в программировании, поскольку она обеспечивает эффективное использование памяти. Когда мы пытаемся вставить новый элемент в динамический массив, он автоматически увеличивается до тех пор, пока для нового элемента не останется места для хранения. Как правило, область увеличивается в два раза.

Что такое динамический массив?

Динамический массив внешне идентичен стандартному массиву, но его размер можно изменить во время выполнения кода. Компоненты Dynamic Array занимают непрерывный блок памяти. После определения массива невозможно изменить его размер. Напротив, динамический массив не похож на статический массив. Даже после того, как он был занят, динамический массив может увеличить свой размер. Элементы можно постоянно добавлять в конечной позиции динамического массива, используя зарезервированное пространство до тех пор, пока оно не будет полностью занято.

Ключевые факторы динамического массива в C++:

Производительность массива определяется его начальным размером и коэффициентом роста. Обратите внимание на следующие моменты:

  • Если массив небольшого размера и имеет более медленный фактор роста, он будет продолжать перераспределять память чаще. В результате производительность массива пострадает.
  • Если массив больше и имеет высокий коэффициент роста, он будет иметь большой объем неиспользуемой памяти. В результате процессы изменения размера могут занять больше времени. В результате производительность массива также пострадает.

Пример 1:

Новое ключевое слово используется для построения динамического массива в следующей программе C++. После этого ключевое слово возвращает ссылку на первый элемент. В разделе заголовка есть включенный файл библиотеки iostream для использования его методов. Также включен файл пространства имен, который позволяет использовать его класс без вызова. Затем вызывается основная функция, в которой мы объявили две переменные «p» и «num» целочисленного типа данных.

На следующем шаге оператор cout печатает оператор «Введите числа». Команда cin принимает ввод от пользователя и размещает его в переменной «num». Следующий шаг имеет переменную-указатель «Array», которая содержит целые значения переменной «num». Введенный пользователем номер будет напечатан с помощью команды cout. Тогда у нас есть для условия цикла который перебирает каждый элемент, введенный пользователем. Массив как «массив» объявляется в команде cin, которая считывает ввод, введенный пользователем.

После завершения цикла на экране консоли будет напечатано выражение «ваши числа». Опять же, у нас есть для условия цикла но на этот раз это для условия цикла перебирает массив элементов. Обратите внимание, что мы разрешили пользователю устанавливать размер массива. В результате размер массива определяется во время выполнения.

используя пространство имен std ;
инт главный ( ) <
инт п , число ;
cout число ;
инт * Множество = новый инт ( число ) ;
cout за ( п = 0 ; п > Множество [ п ] ;
>
cout за ( п = 0 ; п < число ; п ++ ) <
cout >
cout возвращаться 0 ;
>

Пользователю предлагается ввести число в приглашении консоли. После ввода число для размера массива отображает числа заданного размера массива. Результирующий массив отображается в командной строке Ubuntu.

Пример 2:

Список инициализаторов можно использовать для установки динамического массива. Давайте проиллюстрируем это на примере, чтобы увидеть, как это работает. Во-первых, мы добавили файл iostream и файл пространства имен std в раздел заголовка. После этого мы вызвали основную функцию. Логика программы должна быть включена в тело функции. Затем мы определили переменную как «a» целочисленного типа данных.

После объявления целочисленной переменной у нас есть объявление динамического массива как «Arr», в котором используется список инициализаторов. У нас есть четыре целочисленных элемента в массиве. Команда cout напечатает оператор «Элементы массива» перед отображением элементов массива.

На следующем шаге имеем цикл for который перебирает элементы, присутствующие в указанном массиве. С помощью команды cout элементы заданного массива будут напечатаны в командной строке консоли.

Ниже приведен результат, который мы получили в результате выполнения вышеуказанной программы.:

Пример 3:

Как только цель динамического массива достигнута, его следует удалить из памяти компьютера. Для этого можно использовать выражение удаления, чтобы освободить место в памяти и использовать его для хранения дополнительных данных. Мы должны использовать delete[] для удаления динамического массива из памяти системы. Квадратная скобка [] с ключевым словом delete указывает процессору удалить множество переменных, а не только одну.

Приступим к реализации программы. Мы импортировали нужный файл в раздел заголовка. Затем вызывается основная функция. Целочисленные переменные «i» и «no» объявлены в основной функции. После определения этих переменных у нас есть оператор cout «Введите номер», который позволяет пользователю ввести номер. Получаем от пользователя число и сохраняем его в переменной «no» с помощью команды cin.

Затем объявите переменную-указатель «MyArr», которая хранит целые числа в памяти. Число, введенное пользователем, будет напечатано во второй команде cout этой программы. для петли оператор используется для итерации по введенному пользователем номеру. В итоге мы построили оператор delete[], который стирает заданный в программе массив и освобождает место в памяти.

используя пространство имен std ;
инт главный ( ) <
инт я , нет ;
cout нет ;
инт * МояАрр = новый инт ( нет ) ;
cout за ( я = 0 ; я > МояАрр [ я ] ;
>
cout за ( я = 0 ; я < нет ; я ++ ) <
cout >
cout Удалить [ ] МояАрр ;
возвращаться 0 ;
>

После выполнения программы мы получили следующий вывод. Когда программа завершится, массив будет удален.

Пример 4:

Мы можем динамически определить массив указателей размера «X», а затем динамически выделить память размера «Y» для каждой строки, как показано в следующем примере. Сначала мы определили матрицу в разделе заголовка. На следующем шаге у нас есть основная функция, в которой у нас есть переменная-указатель «arr». Переменная-указатель содержит массив размера «X».

Сейчас оператор цикла for выделяет каждой строке размер памяти «Y». Затем у нас есть вложенный цикл для динамического присвоения значений выделенной памяти. Функция rand сгенерирует случайное число для двумерного массива. В следующем вложенном цикле мы напечатали двумерный массив с помощью оператора std:: cout. По завершении программы указанный 2D-массив будет стерт из выделенного пространства памяти, так как мы использовали delete[] в конце.

# определить X 3
# определить Y 4
инт главный ( )
<
инт ** обр = новый инт * [ Икс ] ;
за ( инт я = 0 ; я < Икс ; я ++ ) <
обр [ я ] = новый инт [ Д ] ;
>
за ( инт я = 0 ; я < Икс ; я ++ )
<
за ( инт Дж = 0 ; Дж < Д ; Дж ++ ) <
обр [ я ] [ Дж ] = ранд ( ) % 10 ;
>
>
за ( инт я = 0 ; я < Икс ; я ++ )
<
за ( инт Дж = 0 ; Дж < Д ; Дж ++ ) <
станд. :: cout >
станд. :: cout >
за ( инт я = 0 ; я < Икс ; я ++ ) <
Удалить [ ] обр [ я ] ;
>
Удалить [ ] обр ;

Двумерный массив был сгенерирован и показан на экране консоли ниже.

Вывод

Речь идет об массиве с измененным размером в C++. Мы узнали, что массивы C++ не имеют встроенного метода изменения размера. Но с помощью динамического выделения массива в С++ размер массива можно изменить. В примере мы показали изменение размера динамического массива с помощью нового ключевого слова. Кроме того, мы можем использовать список инициализаторов для инициализации массива. После изменения размера мы также можем освободить место в памяти с помощью удаления []. Эта статья покажет вам, как изменить размер массива в C++.

Изменение размера массива

А нужно увеличить +1 элемент, не потеряв предыдущих данных ?

94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Изменение размера массива
Как без использования функций изменить размер массива? int x=10; int m1; int m2; int m3; iny.

Изменение размера массива
Допустим в main-е я объявил указатель определенного типа и создал переменную int size, затем адрес.

Изменение размера массива
Задача такая: нужно добавить в массив элемент так что бы он стоял в начале массива или.

Изменение размера массива
Здравствуйте. Я хочу написать массив в который записываются введенные данные. Массив должен.

3550 / 2655 / 327
Регистрация: 11.03.2009
Сообщений: 6,073

Копируешь массив во временный, освобождаешь память, выделяешь по новой нужного размера, копируешь из временного обратно в основной, удаляешь временный.

Регистрация: 05.04.2008
Сообщений: 48

Скажите а такой подход не верен?

1 2 3 4 5 6 7 8 9 10
int *x = new int[1]; size_t size; for(int i=0;i100;i++) { x[i] = i; size = _msize( x ); realloc( x,(size + sizeof(int))); }

1664 / 1133 / 80
Регистрация: 21.08.2008
Сообщений: 4,734
Записей в блоге: 1

ЦитатаСообщение от softrix Посмотреть сообщение

Скажите а такой подход не верен?
2021 / 1620 / 489
Регистрация: 31.05.2009
Сообщений: 3,005
А нужно увеличить +1 элемент, не потеряв предыдущих данных ?
использовать std::vector.

Эксперт С++

5041 / 2620 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1

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
/* Изменение размера массива */ int main() { // Размер исходного массива int const a_size = 10; // Выделение памяти под исходнйы массив int * a = new int [a_size]; // Заполнение исходного массива случайными значениями for(int i = 0; i  a_size; ++i) a[i] = rand() % 9 + 1; // Вывод массива на экран std::cout  <"array a: "; std::copy(a, a + a_size, std::ostream_iteratorint>(std::cout, " ")); std::cout  ::endl; int b_size = 0; std::cout  <"enter new size: "; std::cin >> b_size; // Выделение памяти под новый массив и его заполнение int * b = new int[b_size]; memset(b, 0, sizeof(int) * b_size); // Копирование std::copy(a, a + std::min(a_size, b_size), b); // Освобождение памяти из под исходного массива delete[] a; // Вывод нового массива std::cout  <"array b: "; std::copy(b, b + b_size, std::ostream_iteratorint>(std::cout, " ")); std::cout  ::endl; // Память освобождать надо всегда! delete [] b; }

Добавлено через 12 минут
Еще можно поиздеваться и написать подобную функцию

1 2 3 4 5 6 7 8 9 10 11 12
// Изменение размера массива int * Resize(int * a, int oldSize, int newSize) { int * t = new int[newSize]; memset(t, 0, sizeof(int) * newSize); std::copy(a, a + std::min(oldSize, newSize), t); delete[] a; return t; }

Пользуяюсь ею следующим образом

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// Размер исходного массива int a_size = 10; // Выделение памяти под исходнйы массив int * a = new int [a_size]; // Заполнение исходного массива случайными значениями for(int i = 0; i  a_size; ++i) a[i] = rand() % 9 + 1; // Вывод массива на экран std::cout  <"array a: "; std::copy(a, a + a_size, std::ostream_iteratorint>(std::cout, " ")); std::cout  ::endl; int b_size = 0; std::cout  <"enter new size : "; std:: cin >> b_size; a = Resize(a, a_size, b_size); a_size = b_size; // Вывод массива на экран std::cout  <"array a: "; std::copy(a, a + a_size, std::ostream_iteratorint>(std::cout, " ")); std::cout  ::endl;

Добавлено через 1 минуту

ЦитатаСообщение от rangerx Посмотреть сообщение

использовать std::vector.
Но этот вариант конечно самый благоразумный
Регистрация: 05.04.2008
Сообщений: 48

Спасибо за пример, а без использования библиотеки std, как можно сделать ?

Эксперт С++

5041 / 2620 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1

ЦитатаСообщение от softrix Посмотреть сообщение

Спасибо за пример, а без использования библиотеки std, как можно сделать ?
Сейчас на Си накатаю =)
Регистрация: 05.04.2008
Сообщений: 48

Спасибо, а то проблема в том, что эта функция будет в dll, которую я буду к java подключать, не уверен, что данные из вектора смогу нормально в яву передать.

Эксперт CАвтор FAQ

21275 / 8292 / 637
Регистрация: 30.03.2009
Сообщений: 22,656
Записей в блоге: 30

ЦитатаСообщение от softrix Посмотреть сообщение

Скажите а такой подход не верен?

Нет, то что выделено через new нельзя перевыделять через realloc. Разработчики Си++ слишком увлеклись и не предусмотрели человеческого варианта перевыделения памяти средствами языка. Поэтому проще всего с такой памятью работать с malloc/realloc/free, а не с new/delete

Эксперт С++

5041 / 2620 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 1
Без извращенной функции

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 50 51 52 53 54 55 56 57 58
#include #include #include /* Изменение размера массива */ #define min(a,b) (((a) < (b)) ? (a) : (b))// Заполнение массива случайными значениями void random(int * a, int size) { while(size--) *a++ = rand() % 9 + 1; } // Вывод массива на экран void output(int * a, int size) { while(size--) printf("%d ", *a++); printf("\n"); } int main() { int a_size = 10, // Размер исходного массива i = 0, j = 0; // Счетчики // Выделение памяти под исходный массив int * a = (int * )malloc(sizeof(int) * a_size); // Заполнение исходного массива случайными значениями random(a, a_size); // Вывод массива на экран output(a, a_size); // Ввод нового размера int b_size = 0; printf("Enter new Size: "); scanf("%d", &b_size); // Выделение памяти под новый массив int * b = (int * )malloc(sizeof(int) * b_size); memset(b, 0, sizeof(int) * b_size); // Копирование memcpy(b, a, sizeof(int) * min(a_size, b_size)); // Освобождение памяти из под исходного массива free(a); // Вывод нового массива output(b, b_size); // Память освобождать надо всегда! free(b); }

С функцией

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 50 51 52 53 54 55 56 57
#include #include #include /* Изменение размера массива */ #define min(a,b) (((a) < (b)) ? (a) : (b))// Заполнение массива случайными значениями void random(int * a, int size) { while(size--) *a++ = rand() % 9 + 1; } // Вывод массива на экран void output(int * a, int size) { while(size--) printf("%d ", *a++); printf("\n"); } // Изменение размера массива int * resize(int * a, int newsize, int oldsize) { int * b = (int * )malloc(sizeof(int) * newsize); memset(b, 0, sizeof(int) * newsize); memcpy(b, a, sizeof(int) * min(oldsize, newsize)); free(a); return b; } int main() { int a_size = 10; int * a = (int * )malloc(sizeof(int) * a_size); random(a, a_size); output(a, a_size); // Ввод нового размера int b_size = 0; printf("Enter new Size: "); scanf("%d", &b_size); // Тут применяем изврат a = resize(a, b_size, a_size); a_size = b_size; // Вывод нового массива output(a, a_size); free(a); }

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *