【问题标题】:malloc, calloc, and dynamic arraysmalloc、calloc 和动态数组
【发布时间】:2013-06-06 14:12:19
【问题描述】:

这是在一个班级项目中出现的。这个问题可能有点啰嗦,但由于我真的不知道问题到底出在哪里,所以把它完整地拿出来可能会很有用。

假设我们有一个如下形式的结构:

typedef struct
{
    char *name;
    char **friends;
    int numFriends;
} User;

我们有一些结构容器:

typedef struct
{
    User *users;
    int db_size;
} DB;

我们还有两个管理好友的功能:

void makeFriends(char *name1, char *name2, DB *db)
{
    User user1 = findByName(name1);
    User user2 = findByName(name2);

    user1.friends[numFriends] = name2;
    user2.friends[numFriends] = name1;

    user1.numFriends++;
    user2.numFriends++;

    update_db(user1, db);
    update_db(user2, db);
}

void unmakeFriends(char *name1, char *name2, DB *db)
{
    User user1 = getByName(name1);
    User user2 = getByName(name2);

    for (int i = 0; i < user1.numFriends; ++i)
    {
        if (strcmp(user1.friends[i]), name2)
        {
            int size = 0;
            char *newFriendList = malloc(APPROPRIATE_AMOUNT);


            for (int j = 0; j < count; ++i)
            {
                if (j != i)
                {
                    newFriendList[size] = user1.friends[j];
                    size++;
                }
            }

            user1.friends = newFriendList;
            user1.numFriends = size;

            // this breaks things for some reason
            //free(newFriendList);
        }
    }

    // and the same for user2

    for (int i = 0; i < user2.numFriends; ++i)
    {
        if (strcmp(user2.friends[i]), name2)
        {
            int size = 0;

            // this can lead to the corruption of user1's list
            // char *newFriendList = malloc(APPROPRIATE_AMOUNT);
           // but this works fine
           char *newFriendList = calloc(someNum, APPROPRIATE_AMOUNT);


            for (int j = 0; j < count; ++i)
            {
                if (j != i)
                {
                    newFriendList[size] = user2.friends[j];
                    size++;
                }
            }

            user2.friends = newFriendList;
            user2.numFriends = size;

            // this breaks things for some reason
            //free(newFriendList);
        }
    }

    update_db(user1, db);
    update_db(user2, db);
}

我们创建三个用户,给他们一个名字并为他们的朋友列表分配一些内存:

User vladimir = { .name = "Vladimir", .friends = malloc(APPROPRIATE_AMOUNT), 0 };
User estragon = { .name = "Estragon", .friends = malloc(APPROPRIATE_AMOUNT), 0 };
User pozzo = { .name = "Pozzo", .friends = malloc(APPROPRIATE_AMOUNT), 0};

现在,假设弗拉季米尔和爱斯特拉冈想成为朋友,然后爱斯特拉冈和波卓也成为朋友。一段时间过去了,弗拉基米尔和爱斯特拉冈认为他们并不真正喜欢对方,所以他们中的一个与另一个解除了朋友关系。

如果我运行函数unmakeFriends 并使用malloc 两次,第一个用户的朋友列表在第二次期间会损坏(例如名字出现两次或其他未定义的行为) /strong> 循环。如果我使用 calloc 两次,我会得到那个或总线错误。如果我尝试释放内存,则会出现总线错误。如果我按照现在的方式使用代码,一个为malloc,另一个为calloc,它会按预期工作。

发生了什么,为什么?

【问题讨论】:

  • 你需要创建一个好友链表,这样你就可以从列表中间取出一个。列表中的每个条目都分配/释放了自己的内存,而其他条目则保持不变。谷歌“链表 c 教程”。

标签: c arrays malloc calloc


【解决方案1】:

calloc 0 初始化您动态分配的缓冲区。 malloc 只是把它当作垃圾。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-02
    • 2013-11-17
    • 2020-03-22
    • 2010-12-05
    • 2014-11-13
    • 1970-01-01
    相关资源
    最近更新 更多