2014-11-08 85 views
0

在下面的代碼中,我無法弄清楚爲什麼在添加2後運行dump_data()方法時,爲什麼我得到相同的輸出(即同名) (或更多)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? – 2014-11-08 22:47:13

+0

1)userList [numUsers] - > amigos = 0;' - >'userList [numUsers] - > amigos =(Friends){0};'2)'void dump_data(){' - > void dumpData (){'然後[DEMO](http://ideone.com/lDSs6j) – BLUEPIXY 2014-11-08 22:50:58

+0

也許,使用來自控制檯的輸入不同於發佈的代碼。 – BLUEPIXY 2014-11-08 22:56:40

回答

0

問題是,你只在User_struct中只存儲一個char指針,而你在addUser調用中傳遞的指針只是臨時值。您應該將name的類型更改爲具有足夠長度的char陣列,並使用strcpy複製addUser中的名稱。

我不能完全解釋爲什麼這個例子實際上是顯示錯誤,因爲我認爲這兩個名稱字符串應該在整個main()有效,但似乎生成的代碼重複使用「Dan」存儲的位置,因此您得到「吉姆」第二次撥打addUser後再撥打兩次。

+0

是的,在不同情況下,當名稱字符串超出範圍時,代碼將會炸燬。在這裏它將繼續存在,因爲字符串「Dan」和「Jim」最終會出現在數據段中,並且在應用程序的整個生命週期內都有效。 – 2014-11-08 22:58:41