Как установить ссылку указателя через функцию
В C я пытаюсь установить значение указателя, отправив его функции, но значение не изменится вне функции. Вот мой код:
#include <stdio.h>
void foo(char* str) {
char* new_str = malloc(100);
memset(new_str, 0, 100);
strcpy(new_str, (char*)"new test");
str = new_str;
}
int main (int argc, char *argv[]) {
char* str = malloc(100);
memset(str, 0, 100);
strcpy(str, (char*)"test");
foo(str);
printf("str = %s\n", str);
}
Я хочу распечатать:
str = new test
но этот код печатает:
str = test
Любая помощь будет оценена. Спасибо заранее.
Ответы
Ответ 1
Нет пропусков в C. Если вы предоставляете str
в качестве аргумента функции в C, вы всегда передаете текущее значение str
, никогда str
.
Вы можете передать указатель на str в функцию:
void foo(char** pstr) {
// ...
*pstr = new_str;
}
int main() {
// ...
foo(&str);
}
Как говорит Эйко, ваш пример кода утечки первого распределения памяти. Вы больше не используете его, и у вас больше нет указателя на него, поэтому вы не можете его освободить. Это плохо.
Ответ 2
Вам нужно использовать указатель на указатель, untested:
#include <stdio.h>
void foo(char** str)
{
char* new_str = malloc(100);
memset(new_str, 0, 100);
strcpy(new_str, (char*)"new test");
if (str) { /* if pointer to pointer is valid then */
if (*str) /* if there is a previous string, free it */
free(*str);
*str = new_str; /* return the string */
}
}
int main (int argc, char *argv[])
{
char* str = malloc(100);
memset(str, 0, 100);
strcpy(str, (char*)"test");
foo(&str);
printf("str = %s\n", str);
}
Ответ 3
Вы просто переназначаете указатель, который является локальной переменной в foo.
Если вы хотите скопировать строку, используйте strcpy(str, new_str);
Вместо этого вы можете передать ссылку на указатель и переназначить ее, но это может легко привести к утечкам памяти и ее трудно поддерживать.
Изменение: Для псевдо передачи по ссылке см. ответ стива.
Ответ 4
Я сделал это таким образом, возвращая указатель из функции. В этом случае нет причин использовать malloc, поэтому вам не нужно беспокоиться об освобождении.
gcc 4.4.3 c89
char* print_test(char *str)
{
char *new_str = "new_test";
printf("new_str [ %s ]\n", new_str);
str = new_str;
return str;
}
int main(void)
{
char *str = "test";
printf("str [ %s ]\n", str);
str = print_test(str);
printf("str [ %s ]\n", str);
return 0;
}