2013-02-22 5 views
0

Im пытается передать символ array значение персонажу pointer. то это значение возвращается к методу, который его вызывает, но после его получения значение становится мусором. Может кто-нибудь мне помочь?Возвращаемое значение строки становится мусором

#include <stdio.h> 

const char * getname(){ 
    char nam[10]; 
    char * name; 
    gets(nam); 
    name = nam; 
    return name; 
} 
main(){ 
     printf("%s",getname()); 
     getch(); 
} 

все в порядке, пока строка не получает возвращается

+1

Остановить возврат адреса локальной переменной в вызываемой функции. То, что вы делаете, - это неопределенное поведение. И используйте 'fgets()', а не 'gets()'.Эта функция настолько плоха, что она была полностью устранена с C11, устаревшая на C99. – WhozCraig

+0

http://en.wikipedia.org/wiki/Dangling_pointer – Jeyaram

+1

Хотелось бы, чтобы было легко найти эту проблему, это так часто встречается для начинающих. Кроме того, OP, вам не нужна переменная указателя. Массивы распадаются на указатели на первый элемент, когда это необходимо, вы могли бы просто (еще неправильно) написать: 'return nam'; –

ответ

1

Сфера nam локальна функционировать GetName(), вы возвращаете nam адрес через name указатель

const char * getname(){ 
    char nam[10]; 
    : 
    name = nam; 
    return name; 
} 

выделить память для nam; динамически. как:

nam = malloc(sizeof(char)*10); 

дополнительно может быть bufferoverun не использовать gets(), не нравится:

nam = malloc(sizeof(char)*10); 
fgets(nam, 10, stdin); 

Вы также не должны использовать name дополнительный переменный простой return nam хорош.

const char * getname(){ 
    char * nam = malloc(sizeof(char)*10); 
    fgets(nam, 10, stdin); 
    return nam; 
} 
+2

Нет необходимости писать 'sizeof (char)', поскольку он по определению. –

+1

@JanHudec да не нужно :) –

+1

Согласен. Экстра' sizeof (char) 'не болит, забыв' sizeof (int) 'обязательно. –

3

Переменная переменной nam имеет функцию. Это означает, что после завершения функции память для этой переменной освобождается. Таким образом, указатель, указывающий на ту память, которую вы возвращаете, больше не будет действителен.

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

void getname(char *name) 
{ 
    gets(name); 
} 

Вы могли malloc (плохо, потому что тогда вам нужно free снова в какой-то момент):

const char * getname(){ 
    char * name = malloc(10); 
    gets(name); 
    return name; 
} 
+2

+1 для упоминания также «как эта общая проблема обычно решается» design-wise –

+0

Да, на C вам нужно посмотреть, что было выделено и должно быть освобождено там, где все время. C++ может сделать большую часть этого для вас, но в C нет выхода из него. –

+1

У вас есть небольшая ошибка в вашем правильном коде, так как 'gets (name);' –

1

Ваша проблема заключается в том, что return name возвращает адрес переменной стека, тот, который ушел из сферы после завершения функции.

Существует несколько способов исправить это (по крайней мере).

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

char *getname (char *buff) { 
    strcpy (buff, "pax"); 
    return buff; 
} 

char name[20]; 
printf ("Name is '%s'\n", getname (name)); 

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

char *getname (void) { 
    char *buff = malloc (21);  // should really check this for failure. 
    strcpy (buff, "pax"); 
    return buff; 
} 

buff = getname(); 
printf ("Name is '%s'\n", buff); 
free (buff);       // This is important, caller is responsible 
            // for freeing the memory. 
0

Декларирование nam статическую бы также:

const char * getname() { 
    static char nam[10]; 
    ... 

Внимание: Этот код не является поточно-как nam в настоящее время рассматривается как если бы он был объявлен во всем мире.

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