Как уже отмечалось, на самом деле вы можете вернуть указатель на символ. Однако другой распространенный метод заключается в том, чтобы вызывающий передал указатель для заполнения метода вместе с параметром длины. Это делает так, чтобы функция, ответственная за выделение памяти, также была той же функцией, ответственной за освобождение памяти, которая может облегчить просмотр утечек памяти. Это такие функции, как snprintf
и strncpy
.
/* Performs a reverse strcpy. Returns number of bytes written if dst is
* large enough, or the negative number of bytes that would have been
* written if dst is too small too hold the copy. */
int rev_strcpy(char *dst, const char *src, unsigned int dst_len) {
unsigned int src_len = strlen(src); /* assumes src is in fact NULL-terminated */
int i,j;
if (src_len+1 > dst_len) {
return -(src_len+1); /* +1 for terminating NULL */
}
i = 0;
j = src_len-1;
while (i < src_len) {
dst[i] = src[j];
++i;
++j;
}
dst[src_len] = '\0';
return src_len;
}
void random_function() {
unsigned int buf_len;
char *buf;
int len;
const char *str = "abcdefg";
buf_len = 4;
buf = malloc(buf_len * sizeof(char));
if (!buf) {
/* fail hard, log, whatever you want */
return;
}
/* ...whatever randomness this function needs to do */
len = rev_strcpy(buf, str, buf_len);
if (len < 0) {
/* realloc buf to be large enough and try again */
free(buf);
buf_len = -len;
buf = malloc(buf_len * sizeof(buf));
if (!buf) {
/* fail hard, log, whatever you want */
return;
}
len = rev_strcpy(buf, str, sizeof(buf));
}
/* ... the rest of the randomness this function needs to do */
/* random_function has allocated the memory, random_function frees the memory */
free(buf);
}
Это может привести к некоторым накладным расходам, хотя, если вы не знаете, как большой буфер вам нужно, и нужны вызвать функцию дважды, но часто вызывающие имеют хорошее представление о том, как большая потребности буфера быть. Также для этого требуется немного больше логики, чтобы гарантировать, что функция не переполняет данный буфер. Но он несет ответственность за освобождение памяти тем, что выделяет память, а также позволяет передавать локальную стек памяти.
Пример только возвращая char*
:
/* Performs a reverse strcpy. Returns char buffer holding reverse copy of
* src, or NULL if memory could not be allocated. Caller is responsible
* to free memory. */
char* rev_strcpy(const char *src) {
unsigned int src_len = strlen(src); /* assumes src is in fact NULL-terminated */
char *dst;
int i,j;
dst = malloc((src_len+1) * sizeof(char));
if (!dst) {
return NULL;
}
i = 0;
j = src_len-1;
while (i < src_len) {
dst[i] = src[j];
++i;
++j;
}
dst[src_len] = '\0';
return dst;
}
void random_function() {
char *buf;
const char *str = "abcdefg";
/* ...whatever randomness this function needs to do */
buf = rev_strcpy(str);
if (!buf) {
/* fail hard, log, whatever you want */
return;
}
/* ... the rest of the randomness this function needs to do */
/* random_function frees the memory that was allocated by rev_strcpy */
free(buf);
}
Вы можете вернуть указатель, или там что-то более сложное, что вы имели в виду? – Swiss
Статическое распределение! = Автоматическое распределение. Локальные переменные имеют автоматическую продолжительность хранения. Статическая продолжительность хранения означает, что объект существует в течение всего времени работы программы (эти объекты объявляются либо в области файла, либо с использованием 'static' в функции). –
Нет, это то, что я хотел сделать. – theReverseFlick