2011-09-15 2 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 :: queue '을 사용하지 않고 당신 자신의 것을 쓰는 특별한 이유가 있습니까? – Lambdageek

+1

코드를 들여 쓰는 특별한 이유가 있습니까? –

답변

2

이 문제는 생성자에서 동적 배열을 할당하고 있다는 사실로 인해 수 있습니다.

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

코드 논리가 일치하지 않는 것 같습니다. 동적 배열을 할당하는 코드가 있지만 다른 곳에서는 동적으로 할당 된 배열의 개별 요소를 삭제하는 코드가 있습니다.

+0

고마워요!내가 dequeue()를 호출 할 때마다 하나씩 배열을 지우려고하는 것처럼 보입니다. 그리고 dtor에서 다시! 문제 해결됨 – Max

2

이 용의자를 들어, 내 인생에 대한 감사를 알아낼 수 없습니다 :

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

이 함수를 호출하면 queue 포인터가 증가합니다. 이로 인해 new[]에서 가져온 포인터가 delete[]으로 전달 된 포인터와 다릅니다. new[]이 반환 한 포인터와 다른 포인터 delete[]을 전달하면 정의되지 않은 동작이 발생합니다.

개별 tile 초를 delete victim 행으로 삭제하려고하는 것은 말할 필요도 없습니다. 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에 당신은 배열이 아닌 연산자를 삭제 사용하여 삭제합니다

+0

답장을 보내 주셔서 감사합니다. 그래서 MyQueue에 새 개인 회원을 추가했습니다. "tile * start;" 그리고 ctor에서 "queue"와 같게 설정 한 다음 dtor에서 "queue"대신 "start"를 삭제하면 동일한 오류가 발생합니다. 어떤 아이디어? – 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; 
} 

또한 대기열에 당신은 확인하지 않습니다.

관련 문제