2012-06-14 3 views
0

Я пытаюсь изучить C, и теперь я играю со структурами. У меня есть следующий фрагмент кода:Segfault при копировании строки

#include <string.h> 

struct user { 
    unsigned int utime; 
    char *username; 
}; 

void main() 
{ 
    char username[] = "root"; 
    struct user *u; 
    strcpy(u->username, username); 
} 

Но, когда я пытаюсь запустить его, он генерирует ошибку сегментации. Что в этом плохого?

ответ

3

u является указателем на структуру, но вы еще не выделили для нее никакой памяти. Линия должна быть struct user *u = malloc(sizeof(struct user)). Кроме того, вам необходимо будет выделить память для указателя username в вашей структуре до вызова strcpy.

+1

Или просто используйте стек, выделенный 'struct user' (но память для' username 'по-прежнему требуется динамически распределенной). – hmjd

2

Первое, что вам нужно сделать при сбое (например, ошибка сегментации) - запустить вашу программу в отладчике. Это поможет вам определить местоположение аварии, а также позволить вам просматривать переменные, чтобы увидеть, что могло бы вызвать крушение.

Однако в вашем случае это очень просто:

struct user *u; 
strcpy(u->username, username); 

Вы не распределяемая память для u или u->username, что означает, что u может указывать на любое место в памяти и то же самое для u->username.

0

Две вещи

вы не выделенные для переменной структуры «структура пользователя * U;»

, а также вы не выделили памяти * имя пользователя в structore

Для работы

#include <string.h> 
struct user { 
unsigned int utime; 
char *username; 
}; 

void main() 
{ 
    char username[] = "root"; 
    struct user *u=malloc(sizeof(struct user)); 
    u->username=malloc(strlen(username)+1); 
    strcpy(u->username, username); 
} 

Просьба игнорировать, если он имеет какие-либо ошибки синтаксиса

+1

В чистом C возвращаемое значение 'malloc' не должно быть литовым. – LihO

+0

@LihO Я думаю, мы должны, потому что malloc return type void *. Может быть, вы получите предупреждение –

+1

При распределении памяти для строки это должно быть 'strlen (username) + 1', поэтому вы получаете место для завершения' '\ 0''. Или используйте 'strdup' вместо' malloc' и 'strcpy'. –

0

другой путь будет использовать U, как простая переменная: struct user u; а затем получить доступ к utime или имя пользователя с, как это «»:

u.utime = ...; 
u.username = ...; 
0

Параллельно, вы также должны знать о макете памяти, и попытаться рассуждать, что живет где. Отправной точкой для этого было бы - Stanford Pointers pdf Я бы посоветовал, когда вы учитесь и застреваете, попробуйте рисовать поток, доступ к памяти на бумаге, а затем перейдите в отладчик. Я не делал этого, когда узнал, что C first-Memory Visualization - это черта, которая позволяет сделать человека лучшим программистом/отладчиком - из того, что я узнал от своих коллег/прочитал несколько статей в Интернете.