删除动态指针数组中单元格的正确方法
The right way to delete a cell in dynamic array of pointers
在我当前的作业项目中,我构建了一个动态指针数组,其中每个指针指向一个数据结构,其中包含一些字符串(表示用户)。我正在尝试找到正确的方法来删除数组中的特定单元格(或用户),而不会出现任何堆内存问题。
所以我一直在尝试 free
特定的单元格,然后移动其他单元格,这样就不会留下空单元格了。之后,我尝试 "cut" 当前为空的最后一个单元格,realloc
数组为 -1。请参阅我描述问题的代码中的注释。
User** deleteMale(User** pMaleArr, int *maleArrSize, User *onlineUser)
{
int i,j;
//for each array element check if the username matches to the
// connected user
for (i = 0;i < *maleArrSize;i++)
{
if (strcmp(pMaleArr[i]->userName, onlineUser->userName) ==0)
{
//when the user is found, free all fields of the struct
freeUserFields(onlineUser);
//check if it's the last array cell
if (i != *maleArrSize - 1)
{
//shift cells
for (j = i;j < *maleArrSize;j++)
{
pMaleArr[j] = pMaleArr[j + 1];
}//free the last cell
free(pMaleArr[*maleArrSize-1]); //I'm getting a problem here because now the 2 last cells of the array have the same pointer adress.
}
//remove the last cell
pMaleArr = (User **)realloc(pMaleArr, (*maleArrSize
- 1)*sizeof(User*));
if (pMaleArr == NULL)
{
if (*maleArrSize != 1)
{
printf(MA_FAILED);
exit(1);
}
}
break;
}
}
*maleArrSize -= 1;
return pMaleArr;
}
void freeUserFields(User *person)
{
if (person != NULL)
{
//free all fields
free(person->firstName);
free(person->lastName);
free(person->age);
free(person->userName);
free(person->userPassword);
free(person->about);
free(person->hobbies);
//free node itself
free(person);
}
}
所以正如我在上面注意到的,当我尝试 free
最后一个单元格时,为了之后删除它,它也删除了 (last-1) 单元格,因为我复制了他们的地址。在这种情况下,我找不到另一种移动单元格的方法。我可以获得有关如何正确处理它的建议吗?
谢谢!
您不应该释放最后一个单元格,因为您保留了指向该用户的指针。
只需删除第二个免费的。
此外,第二个循环应该达到 j < *maleArrSize -1
。
我已经在您的代码中添加了注释,希望这对您有所帮助:
//check if it's the last array cell
if (i != *maleArrSize - 1)
{
//shift cells
for (j = i;j < *maleArrSize-1;j++)
{
pMaleArr[j] = pMaleArr[j + 1];/* you need till size -1 because of[j+1]*/
}//free the last cell
free(pMaleArr[*maleArrSize-1]); //I'm getting a problem here because now the 2 last cells of the array have the same pointer adress.
}
//remove the last cell- here if the cell to remove was the last one you don't free its inner allocations.
pMaleArr = (User **)realloc(pMaleArr, (*maleArrSize
这段代码存在严重问题:
if (strcmp(pMaleArr[i]->userName, onlineUser->userName) ==0)
{
//when the user is found, free all fields of the struct
freeUserFields(onlineUser); // NOOO !!!
您正在释放传递给控制用户名的结构上的字段,而您应该只访问 *pMaleArr
数组的内容。你应该写:
if (strcmp(pMaleArr[i]->userName, onlineUser->userName) ==0)
{
//when the user is found, free all fields of the struct
freeUserFields(pMaleArr[i]);
而且你不应该释放最后一个单元格。您不释放指针,而是释放它指向的位置。 last 指针指向的内容现在由 previous 指针指向并且必须保留。所以其他部分应该是:
if (i != *maleArrSize - 1)
{
//shift cells
for (j = i;j < *maleArrSize;j++)
{
pMaleArr[j] = pMaleArr[j + 1];
}//just ignore the last cell
}
在我当前的作业项目中,我构建了一个动态指针数组,其中每个指针指向一个数据结构,其中包含一些字符串(表示用户)。我正在尝试找到正确的方法来删除数组中的特定单元格(或用户),而不会出现任何堆内存问题。
所以我一直在尝试 free
特定的单元格,然后移动其他单元格,这样就不会留下空单元格了。之后,我尝试 "cut" 当前为空的最后一个单元格,realloc
数组为 -1。请参阅我描述问题的代码中的注释。
User** deleteMale(User** pMaleArr, int *maleArrSize, User *onlineUser)
{
int i,j;
//for each array element check if the username matches to the
// connected user
for (i = 0;i < *maleArrSize;i++)
{
if (strcmp(pMaleArr[i]->userName, onlineUser->userName) ==0)
{
//when the user is found, free all fields of the struct
freeUserFields(onlineUser);
//check if it's the last array cell
if (i != *maleArrSize - 1)
{
//shift cells
for (j = i;j < *maleArrSize;j++)
{
pMaleArr[j] = pMaleArr[j + 1];
}//free the last cell
free(pMaleArr[*maleArrSize-1]); //I'm getting a problem here because now the 2 last cells of the array have the same pointer adress.
}
//remove the last cell
pMaleArr = (User **)realloc(pMaleArr, (*maleArrSize
- 1)*sizeof(User*));
if (pMaleArr == NULL)
{
if (*maleArrSize != 1)
{
printf(MA_FAILED);
exit(1);
}
}
break;
}
}
*maleArrSize -= 1;
return pMaleArr;
}
void freeUserFields(User *person)
{
if (person != NULL)
{
//free all fields
free(person->firstName);
free(person->lastName);
free(person->age);
free(person->userName);
free(person->userPassword);
free(person->about);
free(person->hobbies);
//free node itself
free(person);
}
}
所以正如我在上面注意到的,当我尝试 free
最后一个单元格时,为了之后删除它,它也删除了 (last-1) 单元格,因为我复制了他们的地址。在这种情况下,我找不到另一种移动单元格的方法。我可以获得有关如何正确处理它的建议吗?
谢谢!
您不应该释放最后一个单元格,因为您保留了指向该用户的指针。
只需删除第二个免费的。
此外,第二个循环应该达到 j < *maleArrSize -1
。
我已经在您的代码中添加了注释,希望这对您有所帮助:
//check if it's the last array cell
if (i != *maleArrSize - 1)
{
//shift cells
for (j = i;j < *maleArrSize-1;j++)
{
pMaleArr[j] = pMaleArr[j + 1];/* you need till size -1 because of[j+1]*/
}//free the last cell
free(pMaleArr[*maleArrSize-1]); //I'm getting a problem here because now the 2 last cells of the array have the same pointer adress.
}
//remove the last cell- here if the cell to remove was the last one you don't free its inner allocations.
pMaleArr = (User **)realloc(pMaleArr, (*maleArrSize
这段代码存在严重问题:
if (strcmp(pMaleArr[i]->userName, onlineUser->userName) ==0)
{
//when the user is found, free all fields of the struct
freeUserFields(onlineUser); // NOOO !!!
您正在释放传递给控制用户名的结构上的字段,而您应该只访问 *pMaleArr
数组的内容。你应该写:
if (strcmp(pMaleArr[i]->userName, onlineUser->userName) ==0)
{
//when the user is found, free all fields of the struct
freeUserFields(pMaleArr[i]);
而且你不应该释放最后一个单元格。您不释放指针,而是释放它指向的位置。 last 指针指向的内容现在由 previous 指针指向并且必须保留。所以其他部分应该是:
if (i != *maleArrSize - 1)
{
//shift cells
for (j = i;j < *maleArrSize;j++)
{
pMaleArr[j] = pMaleArr[j + 1];
}//just ignore the last cell
}