Оставляет в массиве array не более n элементов, начиная с индекса first - C (СИ)
Формулировка задачи:
void slice (Array *array, int first, int n);
Оставляет в массиве array не более n элементов, начиная с индекса first.
Пример. Исходный массив:
1 2 3 4 5 6 7 8 9 0
Вызов:
slice(array, 3, 5);
Результат:
4 5 6 7 8
не работает... что не так? чует моё сердце, что что-то не так с free...
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void* mymalloc(size_t size) {
void *result = malloc(size);
if (result == NULL) {
fprintf(stderr, "mymalloc: не удалось выделить %zd байт\n", size);
exit(EXIT_FAILURE);
}
return result;
}
void* myrealloc(void *ptr, size_t size) {
void *res = realloc(ptr, size);
if (res == NULL && size != 0) {
fprintf(stderr, "myrealloc: не удалось выделить %zd байт\n", size);
exit(EXIT_FAILURE);
}
return res;
}
typedef struct Array {
int *data;
int n;
} Array;
Array* newArray(int n);
Array* copyArray(const Array *array);
void destroyArray(Array *array);
void slice(Array* array, int first, int n);
int main(void) {
Array * array = newArray(5);
for (int i = 0; i < array->n; i++) {
scanf("%d", &(array->data[i]));
}
slice(array, 1, 3);
for (int i = 0; i < array->n; i++)
{
printf("%d ", array->data[i]);
}
printf("\n");
destroyArray(array);
system("pause");
return 0;
}
Array* newArray(int n) {
Array* new_array = (Array*)mymalloc(sizeof(Array));
new_array->n = n;
new_array->data = (int*)mymalloc(n * sizeof(int));
return new_array;
}
Array* copyArray(const Array *array) {
Array* new_array = (Array*)mymalloc(sizeof(Array));
new_array->n = array->n;
new_array->data = (int*)mymalloc(array->n * sizeof(int));
for (int i = 0; i < array->n; i++) {
new_array->data[i] = array->data[i];
}
return new_array;
}
void destroyArray(Array *array) {
free[] array->data;
free array;
}
void slice(Array* array, int first, int n) {
if ((first + n) > array->n) {
printf("Ошибка ввода");
exit(EXIT_FAILURE);
}
Array * temp = newArray(n);
for (int i = 0; i < n; i++) {
temp->data[i] = array->data[i + first];
}
myrealloc(array->data, n);
for (int i = 0; i < n; i++) {
array->data[i] = temp->data[i];
}
array->n = n;
destroyArray(temp);
}Решение задачи: «Оставляет в массиве array не более n элементов, начиная с индекса first»
textual
Листинг программы
/* ANSI C 99 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
typedef int* int_array_t;
int_array_t int_array_new(int size) {
assert(size > 0);
int_array_t array = malloc(sizeof(int) * (size + 1));
if ( ! array )
return NULL;
*array = size;
return array;
}
void int_array_free(int_array_t array) {
free(array);
}
int int_array_size(int_array_t array) {
return *array;
}
int int_array_get_at(int_array_t array, int index) {
assert(index >= 0 && index < *array);
return array[index + 1];
}
void int_array_set_at(int_array_t array, int index, int value) {
assert(index >= 0 && index < *array);
array[index + 1] = value;
}
void int_array_random_fill(int_array_t array, int minval, int maxval) {
for ( int i = 0; i < *array; ++i )
array[i + 1] = rand() % (maxval - minval + 1) + minval;
}
int int_array_dump(int_array_t array, FILE * fout, const char * separator) {
for ( int i = 0; i < *array; ++i )
if ( fprintf(fout, "%d%s", array[i + 1], separator) < 0 )
return -1;
return 0;
}
int_array_t int_array_slice(int_array_t origin, int index, int count) {
assert(index >= 0 && index < *origin && count >= 0);
if ( count == 0 || count + index > *origin )
count = *origin - index;
int_array_t slice = int_array_new(count);
if ( ! slice )
return NULL;
memcpy(&slice[1], &origin[index + 1], count * sizeof(int));
return slice;
}
//////////////////////////////////////////////////////////////////////
#define DEFAULT_SIZE 10
#define MIN_VALUE 0
#define MAX_VALUE 9
int main(void) {
int_array_t arr = int_array_new(DEFAULT_SIZE);
assert(arr);
srand(time(NULL));
int_array_random_fill(arr, MIN_VALUE, MAX_VALUE);
printf("Array:\n");
int_array_dump(arr, stdout, " ");
printf("\nStart index and number of elements to slice: ");
int startIndex, elementsNumber;
if ( scanf("%d%d", &startIndex, &elementsNumber) != 2 ) {
fprintf(stderr, "Wrong input!\n");
int_array_free(arr);
exit(EXIT_FAILURE);
}
int_array_t slice = int_array_slice(arr, startIndex, elementsNumber);
assert(slice);
printf("Slice:\n");
int_array_dump(slice, stdout, " ");
printf("\n");
int_array_free(arr);
int_array_free(slice);
exit(EXIT_SUCCESS);
}
Объяснение кода листинга программы
Код начинается с определения типа указателя на целочисленный массив и прототипов функций. Затем следуют функции для работы с массивом:
- Функция
int_array_newсоздает новый массив заданного размера. Она проверяет корректность размера (чтобы он был больше нуля) и выделяет память под массив. Затем она инициализирует первый элемент массива его размером. - Функция
int_array_freeосвобождает память, выделенную под массив. - Функция
int_array_sizeвозвращает текущий размер массива (т.е. количество элементов в нем). - Функция
int_array_get_atвозвращает элемент массива по заданному индексу. Здесь происходит проверка корректности индекса (чтобы он был больше или равен нулю и меньше размера массива). - Функция
int_array_set_atустанавливает значение элемента массива по заданному индексу. - Функция
int_array_random_fillзаполняет массив случайными целыми числами в заданном диапазоне. - Функция
int_array_dumpвыводит содержимое массива в файл (или на экран, если файл отсутствует или не может быть открыт). - Функция
int_array_sliceсоздает новый массив, содержащий подсрез массива заданного размера, начиная с указанного индекса. Если размер подсреза выходит за пределы массива, то он корректируется до максимально возможного. В основной функции программы создается массив заданного размера, затем он заполняется случайными числами. После этого пользователю предлагается ввести стартовый индекс и количество элементов для вырезания. Если ввод корректен, то создается новый массив, содержащий выделенный подсрез, и выводится на экран. Затем оба массива освобождаются, и программа завершается с успехом. Если ввод некорректен, то выводится сообщение об ошибке, и программа завершается с неудачей.