Если вы хотите выделить внутри функции без назначения возврата выделения обратно в вызывающей функции, то вы не можете просто передать указатель на функцию для выделения.Зачем?C является передачей по значению, и когда переменная передается в качестве параметра, функция получает копию переменной со своим собственным адресом, который сильно отличается от исходного значения в вызывающей программе.Любые изменения, внесенные в переменную в функции, никогда не будут видны обратно в вызывающей стороне.
Чтобы обработать этот сценарий, вы можете передать адрес переменной (например, указатель) и обновить значение по исходному адресу.в памяти.Когда вы говорите о переменной, которая уже является указателем, применяется то же самое, вы должны передать адрес указателя в качестве параметра, чтобы функция получила указатель, содержащий исходный адрес указателя.Затем вы можете выделить / перераспределить, используя исходный адрес указателя и сделать изменения видимыми обратно в вызывающей стороне.Краткий пример может помочь:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NCHAR 64
void fntest (char **s)
{
void *tmp = realloc (*s, NCHAR); /* allocate - using realloc */
if (!tmp) /* validate every allocation */
perror ("realloc-*s");
*s = tmp; /* assign new block of memory (or NULL) to original address */
}
int main (void) {
char *string = NULL; /* must be initialized NULL */
fntest (&string); /* call fntest to allocate string */
if (string) { /* validate allocation succeeded */
strcpy (string, "some stuff"); /* copy some stuff */
printf ("string: %s\n", string); /* output it */
free (string); /* don't forget to free what you allocate */
}
}
Пример использования / вывода
$ ./bin/allocinfn
string: some stuff
Использование памяти / проверка ошибок
$ valgrind ./bin/allocinfn
==7962== Memcheck, a memory error detector
==7962== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7962== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==7962== Command: ./bin/allocinfn2
==7962==
string: some stuff
==7962==
==7962== HEAP SUMMARY:
==7962== in use at exit: 0 bytes in 0 blocks
==7962== total heap usage: 1 allocs, 1 frees, 64 bytes allocated
==7962==
==7962== All heap blocks were freed -- no leaks are possible
==7962==
==7962== For counts of detected and suppressed errors, rerun with: -v
==7962== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Предпочтительная альтернатива - используйте функцию Return
Хотя нет ничего плохого в передаче адреса указателя (и фактически в распределении списков и т. Д. Это требуется)) при простом размещении в отдельной функции вы можете объявить переменную внутри функции, выделить необходимое пространство, проверить выделение выполнено успешно, а затем вернуть указатель на новый блок памяти и назначить его обратно.в main()
.Это немного упрощает вещи.Например:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NCHAR 64
char *fntest (size_t size)
{
void *memptr = malloc (size); /* simply allocate size bytes */
if (!memptr) /* validate! */
perror ("malloc-memptr");
return memptr; /* return pointer to new block (or NULL) */
}
int main (void) {
char *string = fntest (NCHAR);
if (string) { /* validate allocation succeeded */
strcpy (string, "some stuff"); /* copy some stuff */
printf ("string: %s\n", string); /* output it */
free (string); /* don't forget to free what you allocate */
}
}
(вывод и проверка памяти одинаковы)
Просмотрите оба и дайте мне знать, если у вас все еще есть вопросы.