2015-05-29 4 views
0

Я попытался расширить свой список игроков.Использование realloc для изменения размера динамического массива

Когда я использую функцию reallo c, он сохраняет мой плеер, кроме последнего. Я имею в виду, что если бы у меня было 4 игрока в моем массиве, и я попытался расширить свой массив до 7, у меня появился новый массив размером 7 и всего 3 игрока.

Это часть функции:

void initializeListForTree(Player** players, int listSize) 
{ 
    int formulaSize = bla bla bla..... 
    players = (Player **)realloc(players, sizeof(Player *)*formulaSize); 
    if (!players) 
    { 
     printf("memory allocation failed\n"); 
    } 
} 

ответ

0

Больше что-то вроде:

void initializeListForTree(Player*** players, int listSize) 
{ 
int formulaSize = bla bla bla..... 
void *p = realloc(*players, sizeof(Player *)*formulaSize); 

    if (!p) { 
     printf("memory allocation failed\n"); 
    } 
    else { 
    *players = p; 
    } 
} 

и на месте вызова

Player **playerslist = NULL; 

initializeListForTree(&playerslist, 1); 
... 
initializeListForTree(&playerslist, 2); 
etc.. 

Это, конечно, только если ваш тип является указателем на список указателей.

1

Нет, вы не можете изменить players сам() из initializeListForTree() функции. C использует пропуск для значения для передачи аргумента функции. Любые изменения, внесенные в player внутри initializeListForTree(), не будут отражены до фактического аргумента.

Если вам нужно это сделать, вам необходимо передать указатель на players.

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

Это говорит,

  • Пожалуйста do not cast возвращаемое значение malloc() и семьи в C.
  • Пожалуйста, не сохраняйте возвращаемое значение realloc()непосредственно в целевой указатель. В случае отказа realloc() он перезапишет действительный номер.
+0

Итак, вы имеете в виду, что мне нужно сделать что-то вроде этого: player [i] = realloc (player [i], sizeof (Player *)) ??? – motis10

+0

@ user1703871 Я обновил свой ответ, вы можете выбрать любую логику, которая вам подходит. :-) –

+0

@ user1703871 yes, если вы хотите изменить 'player [i]', что вы, безусловно, можете сделать из 'initializeListForTree()'. но тогда, почему вы используете 'realloc()'? что проблема с простой 'malloc()'? –

0

Где realloc() найти расширения памяти:

  • Если есть достаточно свободного места после первоначальной памяти, то он будет использовать, что и исходный адрес не изменится.
  • Если память orignal находится в конце кучи/.., она расширяет память, поэтому исходный адрес не изменяется.
  • Если исходная память находится в середине кучи/.., и недостаточно места, тогда она будет выделять новый блок памяти и скопировать исходную память в новые, чтобы изменить адрес.

Последний случай случается с большой вероятностью, поэтому вам всегда нужно обновить свой адрес после звонка realloc().

И старый адрес может быть помещен в список свободной памяти, вы не должны касаться его больше.Он может быть выделен другим вызовом malloc()/.. в будущем.

И вы можете видеть, что realloc() может быть тяжелым, потому что ему, возможно, потребуется скопировать память, поэтому улучшите код, чтобы избежать его использования, если это возможно.


Вот возможный вариант использования (от TLPI):

// nptr is new pointer, ptr is your original pointer, 

    nptr = realloc(ptr, newsize); 
    if (nptr == NULL) { 
     /* Handle error */ 
    } else { 
     /* realloc() succeeded */ 
     ptr = nptr; 
    } 

Основном, сначала проверьте возвращаемое значение, чтобы увидеть ли удастся:

  • Если не удалось, то оригинальный память останется unchange.
  • Если удастся, назначьте новый адрес исходному указателю.

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


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

Вы можете выбрать коэффициент при изменении размера, например factor = 1.5, средства: new_size = old_size * factor.

+0

Хорошо, вот как работает realloc, но что, по-вашему, мне нужно делать? – motis10

+0

@ user1703871 Я обновил свой ответ. Пока вы понимаете, что на самом деле происходит, вы будете знать, что делать. –

Смежные вопросы