在 C++ 中删除多维结构会导致访问冲突
Posted
技术标签:
【中文标题】在 C++ 中删除多维结构会导致访问冲突【英文标题】:Deleting multidimensional structs in C++ leads to access violations 【发布时间】:2015-08-03 20:17:42 【问题描述】:我有一个指向其他结构的结构。例如,我的结构遵循与此类似的模式(尽管它们要复杂得多)。
typedef struct parent
string name;
int numOfKids;
child* children;
parent
typedef struct child
string name;
details* information;
child
typedef struct details
int age;
string bestFriend;
details
要创建一组父母,我执行以下操作:
Parents * parents = new parents[numParents];
for(int i = 0; i< numParents; i++)
parents[i].children = new children[parents[i].numOfKids];
for (int j = 0; j < parents[i].numOfKids; j++)
parents[i].children[j].information = ( details* )malloc( sizeof( details ) );
memset( parents[i].children[j].details, 0, sizeof( details ) );
后来我试图像这样清理内存:
void clearParents(parents** pParents, int numParents)
for(int i = 0; i< numParents)
for(int j = 0; j< pParents[i]->numOfKids; j++)
free(pParents[i]->children[j].details);
delete [] pParents[i]->children
delete( pParents[i])
这个 clearParents 函数似乎在第一次循环时可以正常工作,但是在返回到内部循环时,它会崩溃
for (int j = 0; j < parents[i].numOfKids; j++)
出现错误:0xC0000005 访问冲突读取位置 0xCCCCCCD4
我猜这与我释放/删除父母数组中的内存有关,同时还尝试继续循环遍历它,但我不确定如何解决问题。
提前感谢您提供的任何见解
【问题讨论】:
omg 为什么所有的数组和new
和指针?是什么设计决定导致了这种情况?
调试!!启动调试器,单步调试代码的每一行,观察变量如何变化。完成此操作之前不要在这里问!
不要将new[]
与delete
混用
@LightnessRacesinOrbit 很遗憾,这不是我的决定。我实际上使用的是 NvAPI,结构代表了 Nvidia 构建的结构。如果您想查看我的实际分配情况,您可以在此处的答案中看到一个示例:***.com/a/12012589/2252761 遗憾的是,Nvidia 没有提供任何关于如何在完成后释放内存的文档,并且我不想把整个结构放在这里,因为如果你以前没有看过它会很吓人。
如果你使用 std::vector,你的很多问题都会消失
【参考方案1】:
您对双指针pParents
感到困惑。您的解除分配模式与分配模式不匹配。我猜你真的想要这样的东西
void clearParents(parents* pParents, int numParents)
for(int i = 0; i< numParents; ++i)
for(int j = 0; j< pParents[i].numOfKids; j++)
free(pParents[i].children[j].details);
delete[] pParents[i].children;
delete[] pParents;
【讨论】:
遗憾的是我无法更改双指针,因为这只是我真实代码的一个示例。正如我在之前的评论中提到的,我实际上使用的是 Nvidia 的 API,这些结构是 Nvidia 调用所需结构的简化版本。双指针还在,delete[] pParents[i] 还能用吗? @LightnessRacesinOrbit 他的例子中的方法头有“parents* pParents”,在我的例子中它有“parents** pParents”。也许我很困惑,但在我看来,他正在删除双指针,而不是最后一次删除,使所有“->”变成“。”如果设计取决于我,我会做这样,但双指针不在我的手中 @TrolliOlli 是的,我现在看到了。虽然我仍然不明白为什么你认为你“需要”双指针。只需在进入函数的途中取消引用一次............ 即使使用双指针delete[] pParents[i]
也是错误的,因为您分配了一次但删除了 numParents
次。当我说你的释放模式与分配模式不匹配时,这就是我的意思。如果你必须有一个双指针,那么也许你需要delete[] *pParents;
?还有free((*pParents)[i].children[j].details);
和delete[] (*pParents)[i].children;
但只是猜测而已。
@john 哦,好吧,这更有意义!但是,我仍然收到错误(即使我删除了整行),所以看起来错误来自 children 或 children[j].details 的内部删除之一。【参考方案2】:
您将new[]
与delete
混合在一起。 pParents
是使用 new[]
声明的,因此您需要在最外面的 for 循环末尾使用 delete[]
将其删除。您不应该尝试删除外部 for 循环中的每个元素。
【讨论】:
以上是关于在 C++ 中删除多维结构会导致访问冲突的主要内容,如果未能解决你的问题,请参考以下文章
C++ - 使用 std::sort 对结构向量进行排序导致读取访问冲突
编写从 C++ 应用程序链接的 Delphi DLL:访问 C++ 接口成员函数会导致访问冲突