【问题标题】:Pointer being freed was not allocated, dynamic array C++被释放的指针未分配,动态数组 C++
【发布时间】:2014-02-23 12:43:44
【问题描述】:

我有a similar issue with C,但我现在的问题实际上是more similar to this.

不幸的是,我只是在学习 C++,我看不到如何将解决方案应用于我之前的问题(如果确实适用的话),而后一个帖子是他的代码的一个特定问题,那就是更多比我自己复杂。

以下是相关代码:

double n1, n2; //temporary data for user entry
int pcount = 0; //size of my array
struct point{double x; double y;};
point *p = new point[1]; //my array
point *tmp;  //temporary array while resizing

while (points >> n1 >> n2){ //for each element the user enters, 
    pcount++; //increase the array size
    tmp = new point[pcount]; //allocate new memory for the array
    tmp = p; //copy the elements from the old to the temporary
    delete [] p; //delete the old array
    p = new point[pcount]; //allocate memory for the new array
    p = tmp; //copy the elements from the temporary to the new array
    delete [] tmp; //delete the temporary
    p[pcount-1].x = n1; //now push back the new element
    p[pcount-1].y = n2;
}

如您所见,ptmp 指向具有初始大小并在几行内释放的数组。至关重要的是,我看不到“未分配被释放的指针”-p 在声明时分配,tmp 在循环内,然后p 被释放并重新分配,然后tmp 被释放,所以循环继续...

我也尝试通过两个循环来实现,但是打印的“点”是(0, 0),不管它们实际上是什么 - 我不知道为什么?

while (points >> n1 >> n2){
    pcount++;
}
p = new point[pcount];
int i = 0;
while (points >> n1 >> n2){
    p[i].x = n1;
    p[i].y = n2;
    i++;
}

【问题讨论】:

  • A) 你有内存泄漏,B) 你重复删除了一些东西,C) 省去你的痛苦并使用std::vector
  • 为什么不分两遍来做呢?首先计算你需要多少点,然后只分配一个点数组?无需处理两个指针和更少的内存碎片。
  • tmp = new point[pcount]; tmp = p; - 如果你立即分配给tmp 别的东西,第一个分配有什么意义?
  • @Borgleader 这是一项未经评估的实验室任务,它注意到std::vector 的存在,但目标是使用和理解动态数组,newdelete []
  • @JHagdahl 我最初尝试过,尽管它不是实验室工作表上列出的方法 - 在我看来,这更有效,因为更少的内存访问。但是,我遇到了这个错误/段错误 11,所以我决定按照表格进行操作。

标签: c++ arrays pointers memory-management dynamic-arrays


【解决方案1】:

您似乎误解了指针的工作原理。 tmp 在循环的第二行中被分配了一个新的 point[],但是在第三行中,tmp 被另一个值覆盖,破坏了对刚刚分配的内存的任何引用......这会导致内存泄漏。我知道,这不是你的问题,但我认为你应该考虑一下整个事情......

【讨论】:

  • 是的,我知道,我现在看到了。我不确定我是如何使tmp '成为' p 的,但我是否需要取消对p 的引用? tmp = new *p?
  • 恐怕我不知道,因为我不知道你的代码应该做什么:-(
  • @OllieFord:您必须使用for 循环一次复制一个元素。
  • @Doberman:我明白他的意思了。我在 OP 中添加了 cmets 以澄清他的思维过程。 (奥利,这就是为什么 cmets 很重要)
【解决方案2】:

这里几乎每一行都有错误:

point *p = new point[1]; // Allocation #1
tmp = new point[pcount]; // Allocation #2
tmp = p;                 // Allocation #2 lost (memory leak)
delete [] p;             // Now 'tmp' is "pointing to junk"
p = new point[pcount];   // Allocation #3
p = tmp;                 // Allocation #3 lost (memory leak), and 'p' is "pointing to junk"
delete [] tmp;           // Segmentation fault, since 'tmp' is "pointing to junk"
p[pcount-1].x = n1;      // Segmentation fault, since 'p' is "pointing to junk"
p[pcount-1].y = n2;      // Segmentation fault, since 'p' is "pointing to junk"

【讨论】:

  • 好吧。谢谢。我搞砸了我的指针。当我做tmp = p; delete [] p; 时,我希望tmp '成为' p。我在 OP 的 cmets 中解决了 tmp 的两次分配问题。
  • 不客气。修复代码后不要忘记接受这个答案... :)
  • 哦,等等,这是我之前在使用两个循环时遇到的问题:它将它们全部返回为 0..:while (points >> n1 >> n2){pcount++}; p = new point[pcount]; int i = 0; while (points >> n1 >> n2){p[i].x = n1; p[i].y = n2; i++} - 这几乎不可读,我将编辑到 OP 中。跨度>
  • 不错。再像那样光顾我,我永远不会“点击 V 并使其变绿”。
  • 这里没有高傲的意思;如果您是这样解释的,我深表歉意,除非您想……否则无需单击 V。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-30
  • 1970-01-01
  • 2014-06-07
相关资源
最近更新 更多