[英]malloc, calloc, and dynamic arrays
這是上課的一個項目。 這個問題可能有點太冗長了,但是由於我真的不知道問題到底在哪里,因此將其完全解決可能很有用。
假設我們具有以下形式的結構:
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};
現在,假設弗拉基米爾(Vladimir)和埃斯特拉貢(Estragon)想成為朋友,然后埃斯特拉貢(Estragon)和波佐(Pozzo)也成為了朋友。 一段時間過去了,弗拉基米爾(Vladimir)和埃斯特拉貢(Estragon)決定他們彼此並不真正喜歡,所以他們中的一個解除了彼此的友誼。
如果我運行函數unmakeFriends
並使用malloc
兩次, 則在第二個循環期間, 第一個用戶的朋友列表會損壞(例如名稱出現兩次或其他未定義的行為)。 如果我兩次使用calloc,則會收到該錯誤或總線錯誤。 如果嘗試釋放內存,則會出現總線錯誤。 如果我按現在的方式使用代碼,一個作為malloc
,另一個作為calloc
,它將按預期工作。
發生了什么,為什么?
calloc 0初始化您動態分配的緩沖區。 malloc只是將其保留為垃圾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.