Используйте realloc с указателем на задачу указателя

Я практикую любые навыки, чтобы выполнить задачу. Я суммирую с этим упражнением: У меня есть 2 массива заказов в одном массиве, первый элемент в первом массиве больше, чем последний элемент первого массива. Мне нужно упорядочить массив только с помощью realloc() и memcpy (не использовать malloc/new arrays). и вернуть размер первого массива - K. (0 <= k < n ). функция получает адрес указателя на динамический массив с n числами.

для исполняемого файла: {32,64,66,69,72,78,81,87,94,95,1,2,4,8,17}

У меня небольшая проблема с realloc() с указателем. Я пытаюсь увеличить массив в размере первого массива, скопируйте первую часть в конец массива, а затем скопируйте вторую часть в начало, и затем скопируйте последнюю часть в следующую часть, а затем снова realloc() до большого размера.

мой код до сих пор:

int arrangeArray(int** arr, int n)
{
int i = 0;
int first_size;
int second_size;
int new_size;
while (*(*arr + i) < *(*arr + i + 1)) { // find the size of the first array 
    num = *(*arr + i + 2);
    i++;
}
first_size = i + 1;;

second_size = n - i;
new_size = n + first_size;

*arr = (int*)realloc(*arr, new_size * (sizeof(int))); // enlarge the size of the array;

memcpy((*arr) + n, (*arr), sizeof(int) * first_size); // copy the first part to the end of the array;

memcpy((*arr), (*arr) + first_size, sizeof(int) * second_size); // copy the second array to the first of the new;

memcpy((*arr) + second_size - 1, *arr + n, sizeof(int) * first_size); // copy the last array to the last;

*arr = (int*)realloc(*arr, (n * (sizeof(int)))); // resize to the orginal size;

return first_size;
}

Вы не должны использовать arr после realloc(arr, ...)

Cosinus 21.03.2022 10:12

Да, это та часть, в которой я стек... Можете ли вы объяснить мне, как использовать realloc с указателем на указатель?

Yoav Lavie 21.03.2022 10:16
new_arr = realloc(arr, new_size); if (new_arr) { arr = mew_arr; } else { /* Handle error */ }
Cosinus 21.03.2022 10:21

что с кастингом до? и размер int?

Yoav Lavie 21.03.2022 10:27

В этом коде гораздо больше ошибок, чем просто realloc (что ужасно неправильно само по себе). (sizeof(new_ar)- second_size) будет абсолютно нет делать то, что вы думаете. sizeof(nerw_ar) — это размер указатель. Ваш пост должен включать пример расширения просто, чтобы прояснить странность перетасовки данных, которую вы пытаетесь выполнить, кстати.

WhozCraig 21.03.2022 10:52
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
5
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы используете malloc, free, realloc и т. д. с «указателем на T», где T — любой тип. В вашем случае T = int*, что может сбивать с толку, но в этом нет ничего особенного.

Для массива с n элементами вы должны написать

T* array = (T*) malloc(n * sizeof (T))

или

T* array = (T*) calloc (n, sizeof (T)). 

Чтобы перераспределить массив, у вас есть два варианта: либо вы молитесь о том, чтобы realloc никогда не терпел неудачу, либо вы пишете код для обработки ошибок. Один из способов справиться с этим:

T* array = ...; // This is where you created and filled the array
T* oldArray = array;
array = (T*) realloc (array, n * sizeof (T));

if (array == NULL) {
    // realloc failed, oldArray contains the original data.
    // Do what you can to handle the failure
    array = oldArray;
    return;
}

// Now you are NOT allowed to use oldArray anymore. It's only valid if
// realloc failed. 

Имейте в виду две вещи: Если вы действительно сжимаете массив, вы должны перераспределить элементы до, перераспределив их так, чтобы в конце было отброшено. ОДНАКО realloc может потерпеть неудачу, если вы сделаете массив меньше! В этом случае вы продолжаете использовать исходный массив. И он может (и довольно часто будет) возвращать указатель, отличный от исходного.

Если вы сделаете массив больше, а realloc не сработает, то новый массив будет начинаться с исходных данных, за которыми следует мусор.

И обратите внимание, что вы должны постоянно следить за размером массива. И, как упоминалось в комментарии, sizeof возвращает размер указателя, поэтому, скорее всего, 4 или 8, а не размер выделенной памяти.

И, пожалуйста, не используйте сложение + разыменование для арифметики указателя. Гораздо читабельнее писать a[i] вместо *(a + i).

Я до сих пор не понимаю, как увеличить массив с помощью realloc? new_ar = (int*)realloc(arr, new_size * (sizeof(int)));

Yoav Lavie 21.03.2022 12:05

Другие вопросы по теме