2014-11-08 143 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