2014-11-08 2 views
0

В следующем коде я не могу понять, насколько я должен использовать тот же результат (то есть то же имя) при запуске метода dump_data() после добавления 2 (или более) User_struct (с разными именами) с помощью метода addUser().Динамически распределенный список динамически выделяемых структур переписывается

struct Friends_struct { 
    struct User_struct *this; 
    struct Friends_struct *next; 
}; 

typedef struct Friends_struct *Friends;  

typedef struct User_struct { 
    const char *name; 
    Friends amigos; 
} User; 

static User **userList;    // global table of users 
static int numUsers;    // global number of users 
static int tableSize;    // global size of table 


void create_amigonet() {  
    tableSize = INIT_TABLE_SIZE; 
    numUsers = 0; 

    userList = malloc(tableSize * sizeof(User *)); 
} 

void addUser(const char *name) { 
    userList[numUsers] = malloc(sizeof(User)); 
    userList[numUsers]->name = name; 
    userList[numUsers]->amigos = 0; 

    numUsers++; 

    if (numUsers == tableSize) { 
     tableSize += INIT_TABLE_SIZE; 

     User **moreUsers; 
     moreUsers = realloc(userList, tableSize * sizeof(User *)); 
     userList = moreUsers; 
    } 
} 

void dump_data() { 
    for (int i=0; i<numUsers; i++) { 
     printf("%s; friends:", userList[i]->name); 
    } 

    printf("\n"); 
} 

Различные .c файл:

void do_add(const char *name) { 
    addUser(name); 
} 

int main(void) { 
    create_amigonet(); 
    do_add("Dan"); 
    do_add("Jim"); 
    dump_data(); 
} 

Если это выполняется, то выход я ожидал бы что-то вроде

Dan; friends: 
Jim; friends: 

пока я получаю

Jim; friends: 
Jim; friends: 

Как/где я переписываю свои данные?

+0

Не компилируется. Когда я исправляю ошибки компиляции, он работает так, как ожидалось. 'userList [numUsers] -> amigos = 0;' неверно. amigos - это структура 'Friends', которую вы не можете присвоить ей значение 0. Также dumpData или dump_data? –

+0

1) 'userList [numUsers] -> amigos = 0;' -> 'userList [numUsers] -> amigos = (Друзья) {0};' 2) 'void dump_data() {' -> 'void dumpData() {'then [DEMO] (http://ideone.com/lDSs6j) – BLUEPIXY

+0

возможно, используя ввод с консоли в отличие от опубликованного кода. – BLUEPIXY

ответ

0

Проблема в том, что вы храните только указатель char в User_struct, а указатели, которые вы передаете в звонках addUser, являются временными. Вы должны изменить тип name на массив достаточной длины и использовать strcpy для копирования имени в пределах addUser.

Я не могу полностью объяснить, почему пример действительно показывает ошибку, потому что я думал, что обе строки имен должны быть действительными в течение main(), но кажется, что сгенерированный код повторно использует место, где хранился «Дэн», и поэтому вы получаете «Джим» дважды после второго звонка addUser.

+0

Да, при разных обстоятельствах код взорвался бы, когда строки имен вышли из сферы действия. Здесь он сохранится, поскольку строки «Дэн» и «Джим» попадут в сегмент данных и будут действительны для срока службы приложения. –

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