2014-10-13 2 views
0

Это вопрос практики экзамена, который я имею некоторые трудности с:Практика экзамена Вопросы

struct bodytp // Is there an error? 
{ 
    char *name; // If so, fix the error. 
    int len; 
}; 

main() 
{ 
     struct bodytp person; 
     keepname(&person , "Waterman"); 
     printf("%s\n", person.name); 
} 

void keepname(struct bodytp *onept, const char *last) 
{ 
    int len; 
    char *tpt; 
    for (len = 0; last[len] != '\0';) 
    len++; 
    char name[len+1]; 
    for (tpt = name; *tpt++ = *last++;) 
    ; 
    onept->name = name; 
    onept->len = len; 
} 

я определил, что есть ошибка, а когда я запускаю его, я получаю кучу мусора от Printf. Я также определил, что personname действительно «Waterman» после вызова функции keepname. Я попытался разыменовать person.name до person -> name, изменив проблему из вопроса на основе стека на вопрос, основанный на куче, исключив оператор амперсанда и построив структуру, но ничего не получилось. Может ли кто-нибудь направить меня в правильном направлении? Заранее спасибо.

+5

'onept-> name = name;' здесь вы назначаете адрес локальной переменной, чье время жизни завершено после вызова функции. –

+0

Если он отвечает, это должен быть ответ @BlueMoon :) – Yann

+1

len на самом деле не проблема, поскольку он инициализирован в цикле ... – tomsoft

ответ

0

Есть ли ошибка? не

struct bodytp // Is there an error? 
{ 
    char *name; // If so, fix the error. 
    int len; 

}; 

Нет там никакой ошибки. Это допустимое определение структуры.

Теперь ошибки следуют. :)

Функция основной должна быть объявлена ​​как

int main(void) 

Хотя это не ошибка, тем не менее, было бы лучше, что перед вызовом функции есть woud быть прототип функции

keepname(&person , "Waterman"); 

Программа имеет неопределенное поведение, поскольку существует указание указателя на структуру по адресу локального массива, который будет равен d estroyed после выхода из функции

void keepname(struct bodytp *onept, const char *last) 
{ 
    //... 
    char name[len+1]; 
    //... 
    onept->name = name; 
    //... 
} 

Действительной функции может быть определен как

void keepname(struct bodytp *onept, const char *last) 
{ 
    int len = 0; 
    char *tpt; 

    while (last[len] != '\0') len++; 

    char *name = malloc(len + 1); 

    for (tpt = name; *tpt++ = *last++;) ; 

    onept->name = name; 
    onept->len = len; 
} 

В этом случае вы должны освободить память в Кутаиси главных.

Примите во внимание, что вы используете стандартные функции C strlen и strcpy в функции.

0

Вам необходимо выделить память для имени в куче.

void keepname(struct bodytp *onept, const char *last) 
{ 
    int len; 
    char *tpt; 
    for (len = 0; last[len] != '\0';len++); 
    char *name=malloc(len+1); 
    onept->name = name; 
    onept->len = len; 
    for (; *name++ = *last++ ;); 
} 
+0

Существует конечное условие: '* tpt ++ = * last ++'. Возвращаемое значение этого оператора - это назначенное значение. В тот момент, когда встречается '\ 0', он оценивается как« false », и цикл останавливается. – zegkljan

+0

вы правы, удалены – tomsoft

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