Когда вы передаете массив указателей на функцию до realloc
, у вас в основном есть 2 варианта; (1) передают адрес массива функции (то есть &array
) в качестве параметра, то есть определение функции будет reallocfoo (int ***array, size_t* size)
или (2) назначить возврат функции в вызывающей процедуре. (например, array = reallocfoo (array, &size);
)
Поскольку вам уже даны ответы на (1), давайте посмотрим, как вы будете реализовывать и использовать (2). Примечание: нет необходимости делать вашу функцию type
из массива, он просто возвращает адрес памяти, поэтому использование указателя общего назначения void
в порядке. Например:
void *xrealloc2 (void **memptr, size_t *n)
{
void *tmp = realloc (memptr, *n * 2 * sizeof tmp);
if (!tmp) {
fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
return NULL;
}
memptr = tmp;
memset (memptr + *n, 0, *n * sizeof tmp);
*n *= 2;
return memptr;
}
Также примечания поскольку вы перераспределить массив указателей, нет необходимости передавать размер шрифта (указатель указатель является указатель - во всех случаях мы заботимся о Вот). Положив это на работу, поскольку вы не передаете адрес своего массива, вам нужно будет назначить возврат для завершения перераспределения. (Много, как вы делали в коде выше) например .:
if (ridx == rmax) /* if realloc is needed */
ia = xrealloc2 ((void **)ia, &rmax);
Примечание: текущее количество указателей (rmax
) передается как указатель, поэтому его значение может обновляться в два раза тока в функции перераспределения. (поэтому, когда вы закончите в следующий раз, вы можете перераспределить на основе правильного обновленного текущего номера). Соединяя все части вместе, вы получите короткий пример, который просто заставляет перераспределять два раза. Кроме того, исходное распределение также помещается в функцию, чтобы сохранить основную часть кода в порядке, а возврат проверяет распределение в функции. (Вы можете решить, как вы справляетесь исчерпание памяти - NULL
возврата или exit
, примеры и показаны в двух функциях)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define RMAX 2
#define COLS 5
void *xcalloc (size_t n, size_t s);
void *xrealloc2 (void **memptr, size_t *n);
int main (void) {
int **ia = NULL;
size_t rmax = RMAX;
size_t rows = 0;
size_t ridx = 0, cidx = 0;
srand (2275311); /* arbitrary repeatable seed */
ia = xcalloc (RMAX, sizeof *ia);
/* intentionally force reallocation */
while (ridx < 3 * RMAX) {
ia[ridx] = xcalloc (COLS, sizeof **ia);
for (cidx = 0; cidx < COLS; cidx++)
ia[ridx][cidx] = rand() % 1000 + 1;
ridx++;
if (ridx == rmax)
ia = xrealloc2 ((void **)ia, &rmax);
}
rows = ridx;
printf ("\n the reallocated 2D array elements are:\n\n");
for (ridx = 0; ridx < rows; ridx++) {
for (cidx = 0; cidx < COLS; cidx++)
printf (" %4d", ia[ridx][cidx]);
putchar ('\n');
}
putchar ('\n');
for (ridx = 0; ridx < rows; ridx++)
free (ia[ridx]);
free (ia);
return 0;
}
/** xcalloc allocates memory using calloc and validates the return.
* xcalloc allocates memory and reports an error if the value is
* null, returning a memory address only if the value is nonzero
* freeing the caller of validating within the body of code.
*/
void *xcalloc (size_t n, size_t s)
{
register void *memptr = calloc (n, s);
if (memptr == 0)
{
fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
exit (EXIT_FAILURE);
}
return memptr;
}
/* realloc array of pointers ('memptr') to twice current
* number of pointer ('*nptrs'). Note: 'nptrs' is a pointer
* to the current number so that its updated value is preserved.
* no pointer size is required as it is known (simply the size
* of a pointer
*/
void *xrealloc2 (void **memptr, size_t *n)
{
void *tmp = realloc (memptr, *n * 2 * sizeof tmp);
#ifdef DEBUG
printf ("\n reallocating %zu to %zu\n", *n, *n * 2);
#endif
if (!tmp) {
fprintf (stderr, "%s() error: virtual memory exhausted.\n", __func__);
return NULL;
}
memptr = tmp;
memset (memptr + *n, 0, *n * sizeof tmp);
*n *= 2;
return memptr;
}
После компиляции кода и запустить его, он подтвердит, что вместо того, чтобы просто максимальные 2
строк (указатели), первоначально выделенные, перераспределение происходит в два раза увеличивая их число до 8
(например 2->4->8
), так что все 6 рядов чисел, присвоенных правильно выделяются:
the reallocated 2D array elements are:
155 573 760 410 956
553 271 624 625 934
259 291 811 161 185
756 211 16 6 449
124 869 353 210 317
310 181 897 866 831
Если у вас есть какие-либо вопросы, дайте мне знать. Не забывайте, что всегда запускайте любой код, который выделяет или перераспределяет через valgrind
(или аналогичную программу проверки памяти), чтобы обеспечить правильное использование вашей памяти и освободить всю память, которую вы выделяете.
==29608== Memcheck, a memory error detector
==29608== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==29608== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==29608== Command: ./bin/realloc2d
==29608==
the reallocated 2D array elements are:
<snip>
==29608==
==29608== HEAP SUMMARY:
==29608== in use at exit: 0 bytes in 0 blocks
==29608== total heap usage: 9 allocs, 9 frees, 232 bytes allocated
==29608==
==29608== All heap blocks were freed -- no leaks are possible
==29608==
==29608== For counts of detected and suppressed errors, rerun with: -v
==29608== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Вы можете скомпилировать код выше с -DDEBUG
флагом, чтобы распечатать на stdout
каждый раз, когда он перераспределяет и обеспечить текущее количество указателей, выделенных. Удачи.
Вам не нужно использовать '(int **) realloc ...'. –
Почему бы * не * быть ненужными данными в новых строках и столбцах? – immibis
Я заполняю новые пробелы циклом, я изолировал проблему от этой части кода, но я не могу ее найти, как ни странно, если я просто добавлю 1 столбец и 1 строку, это отлично работает или я делаю матрица меньше работает отлично, но когда я пытаюсь добавить более 1 строки или столбца, я получаю ошибку – gabevt