2011-09-15 62 views
0

我得到了标题中的错误,当我尝试运行我的代码...... 这里就是我正在*** glibc的***免费():无效的指针:

class MyQueue { 
    tile* queue; 
    int size; 
public: 
    MyQueue(int cap); 
    ~MyQueue(); 
    void enqueue(tile t); 
    tile dequeue(); 
    bool isEmpty(); 
}; 

void MyQueue::enqueue(tile t) { 
queue[size] = t; 
size++; 
} 

tile MyQueue::dequeue() { 
tile temp = queue[0]; 
tile* victim = queue; 
queue++; 
delete victim; 
return temp; 
} 

bool MyQueue::isEmpty() { 
if (size == 0) 
    return true; 
else 
    return false; 
} 

MyQueue::MyQueue(int cap) { 
queue = new tile[cap]; 
size = 0; 
} 

MyQueue::~MyQueue() { 
delete[] queue; 
} 

int main(int argc, char *argv[]) { 
tile tile1; tile1.type = '1'; 
tile tile2; tile2.type = '2'; 
tile tile3; 

MyQueue q(10); 
q.enqueue(tile1); 
q.enqueue(tile2); 
tile3 = q.dequeue(); 
cout<<tile3.type<<" =1?"<<endl; 
return 0; 
} 

的valgrind :

==4506== Mismatched free()/delete/delete [] 
==4506== at 0x4C27FFF: operator delete(void*) (vg_replace_malloc.c:387) 
==4506== by 0x400CD2: MyQueue::dequeue() (MyQueue.h:37) 
==4506== by 0x400DD7: main (p1.cpp:24) 
==4506== Address 0x5964040 is 0 bytes inside a block of size 120 alloc'd 
==4506== at 0x4C28658: operator new[](unsigned long) (vg_replace_malloc.c:305) 
==4506== by 0x400D35: MyQueue::MyQueue(int) (MyQueue.h:49) 
==4506== by 0x400D9F: main (p1.cpp:21) 
==4506== 
1 =1? 
==4506== Invalid free()/delete/delete[] 
==4506== at 0x4C27C7B: operator delete[](void*) (vg_replace_malloc.c:409) 
==4506== by 0x400D74: MyQueue::~MyQueue() (MyQueue.h:54) 
==4506== by 0x400E2F: main (p1.cpp:21) 
==4506== Address 0x596404c is 12 bytes inside a block of size 120 free'd 
==4506== at 0x4C27FFF: operator delete(void*) (vg_replace_malloc.c:387) 
==4506== by 0x400CD2: MyQueue::dequeue() (MyQueue.h:37) 
==4506== by 0x400DD7: main (p1.cpp:24) 
==4506== 
==4506== 
==4506== HEAP SUMMARY: 
==4506==  in use at exit: 0 bytes in 0 blocks 
==4506== total heap usage: 1 allocs, 2 frees, 120 bytes allocated 
==4506== 
==4506== All heap blocks were freed -- no leaks are possible 
==4506== 
==4506== For counts of detected and suppressed errors, rerun with: -v 
==4506== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4) 

似乎是愚蠢的东西,但我无法弄清楚了我的生活,感谢您的帮助

+0

是否有一个特定的原因,你不使用'std ::队列'并写你自己的呢? – Lambdageek

+1

有没有特别的原因,你不缩进你的代码? –

回答

2

问题可能这样的事实:在构造函数中你是动态分配的数组到期。

tile* victim = queue; 
queue++; 
delete victim; 

它看起来像代码中的逻辑不匹配。一方面有代码分配动态数组,但在其他地方它删除动态分配数组的单个元素。

+0

谢谢!看起来我试图一次一个地删除数组,然后再次在dtor中调用dequeue()。问题解决了 – Max

2

这是犯罪嫌疑人:

tile MyQueue::dequeue() 
{ 
    tile temp = queue[0]; 
    tile* victim = queue; 
    queue++; // <----- Note this! 
    delete victim; 
    return temp; 
} 

调用此函数将增加queue指针。这会导致您从new[]获得的指针与您传递给delete[]的指针不同。传递一个指向delete[]的指针与new[]返回的指针不同会产生未定义的行为。

更不用说您试图用delete victim行删除个人tile s。您无法删除使用new[]分配的阵列中的单个项目,删除项目的唯一方法是一次删除整个阵列。

int main(int argc, char *argv[]) 
{ 
    tile tile1; tile1.type = '1'; 
    tile tile2; tile2.type = '2'; 
    tile tile3; 

    MyQueue q(10); // calls new[] and assigns pointer to queue. 
    q.enqueue(tile1); 
    q.enqueue(tile2); 
    tile3 = q.dequeue(); // **increments queue** 
    cout<<tile3.type<<" =1?"<<endl; 
    return 0; 
    // When MyQueue is destroyed, its destructor passes new value of 
    // queue to delete[], which of course doesn't work. 
} 

除非这是家庭作业,你真的应该使用std::queue代替。它已经过全面测试,并且是C++标准库的一部分。另外,请拿起a good introductory C++ book。你的问题表明了对内存管理如何工作的根本性误解。

queue = new tile[cap]; 

deque使用非数组delete运算符将其删除:

+0

感谢您的回复...所以我添加了一个新的私人会员到MyQueue “tile * start;” 并设置它等于ctor中的“队列”,然后在dtor中删除“start”而不是“queue”,并且我得到相同的错误。有任何想法吗? – Max

+0

@Max:您的注释很混乱。一个由代码构成的测试用例是唯一的方法。使用http://ideone.com。 –

1

您没有分配您推送的原始磁贴,因此您不应该在此功能中取消分配它。你已经在析构函数中处理了总数组的释放,这很好。

tile MyQueue::dequeue() 
{ 
    assert(size != 0); // could throw an exception here 
    tile temp = queue[size-1]; 
    --size; 
    return temp; 
} 

另外,在排队,你不检查你是否会增加一个元素过去你分配的数组所以另一个断言/异常应放在那里的大小。

相关问题