Проблема с возвратом строки из функции - PullRequest
0 голосов
/ 14 апреля 2011

У меня проблемы с основными принципами строк в C. У меня есть функция:

char *editStr(char *str) {
char new[strlen(str)];
... do some editing ...
return new;
}

Как бы я вернул массив символов с именем "new". Как я понимаю, возвращаемое значение функции - это char *, что означает, что он запрашивает указатель на первый символ строки. Прямо сейчас, я думаю, проблема в том, что я возвращаю символ массива. Я попытался вернуть указатель на первый символ в «новом», но это тоже не сработало. Я попытался "вернуть * новый [0]". Мои знания о строках плохие.

Ответы [ 7 ]

2 голосов
/ 14 апреля 2011

Здесь есть различные проблемы, но проблема с массивом / указателем с return new; не является одной из них.

Сначала вы хотите:

char new[strlen(str) + 1];

Так что у вас достаточнокомната для нулевого терминатора.

Ваш new размещен в стеке, поэтому его возврат вызовет только горе и замешательство;вместо этого вы захотите:

char *new = malloc(strlen(str) + 1);

, чтобы память по-прежнему работала, когда функция вернется.

Что касается вашего реального вопроса, то массив в C - это адреспервый элемент, так что ваш return new; в порядке (в зависимости от проблемы стека и кучи, упомянутой выше).C-массивы распадаются на указатели в мгновение ока, поэтому вам не нужно беспокоиться о возврате массива при объявлении функции, возвращающей указатель.

2 голосов
/ 14 апреля 2011

Вы возвращаете указатель на то, что вы создали в стеке.Вы не можете этого сделать.

Вам нужно malloc() памяти из кучи и вернуть это (а затем free() позже)

char *editStr(char *str) {
    char *newArray = malloc(strlen(str) +1);
     ... do some editing ...
     return newArray;
}

РЕДАКТИРОВАТЬ : Потому что я забыл добавить 1 для ограничителя строки.Вы также можете использовать strdup(), если хотите начать с копии исходной строки.

1 голос
/ 14 апреля 2011

Вот что я вижу:

  1. Слово "новый" является ключевым словом C ++.Не используйте его для присвоения имени переменной
  2. Если вы хотите редактировать строку, отредактируйте str напрямую.
  3. Если вам нужно сделать копию, используйте malloc (strlen (str)) для выделения дополнительной памяти.
0 голосов
/ 14 апреля 2011

Если вы работаете в однопоточной среде и значение используется немедленно, вы можете сделать внутренний буфер статическим, и он будет доступен даже после выхода из функции:

 char *editStr(char *str) {
     static char new[strlen(str)];
     ... do some editing ...
     return new;
 }

Вы также можете использовать простой старый стиль sprintf: передать указатель на буфер функции и заполнить его внутри.

 int editStr(char *str, char *new, int new_size) {
     ... do some editing ...
     return 0; //can return error
 }
0 голосов
/ 14 апреля 2011

Когда вы создаете обычный массив C, он будет существовать только внутри области, в которой вы его создали (в данном случае, функция editStr()), и будет уничтожен, как только вы вернетесь из этой функции.Следовательно, если вы возвращаете указатель массива, он станет бесполезным, и если вы попытаетесь его использовать, ваша программа, скорее всего, вылетит.

Вместо этого вы должны динамически распределять массивы, используя malloc().Его довольно просто использовать:

 char *a = (char*) malloc(sizeof(char) * 5);

Это создаст массив из 5 char с, который вы можете использовать, и даже передадите его между функциями.Однако они не уничтожаются автоматически, когда выпадают из области видимости, поэтому вам нужно уничтожить их вручную, используя free(a), когда вы закончите с указателями, иначе вы получите утечку памяти.

См. Также:

0 голосов
/ 14 апреля 2011

Эта статья описывает проблему, с которой вы столкнулись, и как с ней бороться.

Лучший способ вернуть указатель на массив в C такой:

char *getArr()
    {
    char *retbuf = malloc(25);
    if(retbuf == NULL)
        return NULL;
    return retbuf;
    }
0 голосов
/ 14 апреля 2011

new переменная размещена в стеке, и вы не можете вернуть ссылку на переменную стека.

char *editStr(char *str) {
     char new[strlen(str)];
     ... do some editing ...
     return new;
} // At this point, Unwinding of stack begins.
  // new is on stack and the memory allocated to it is deallocated.
  // So, the returned reference is only pointing to garbage.

Вместо этого вы должны использовать malloc и free, как только это будет сделано.

char *new = malloc( strlen(str) + 1 ) ; // +1 for the the termination character
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...