2016-12-15 4 views
1

配列で循環バッファの実装を実行しようとしています。データを構造化し、プッシュ、ポップなどのいくつかの方法で管理します。プログラムは多かれ少なかれ機能的であり、期待どおりに動作しますが、私はvalgrindテストでエラーに遭遇します。そして私は自分のコードに何が間違っているかを知ることができません。それは私の構造体でポインタを介してデータを管理するように思えるが、重大な問題です。誰かが私を正しい方向に向けることができれば、私はとても感謝しています。私はこの時点で本当に失われています。構造体のポインタからデータを取得する "無効な読み取り/書き込み"

これは私の構造体がどのように見えるかです:
(コメントコードがmemcpyのようほとんど同じエラーを生成します)

int* increase(int* point, queue_t* queue){ 
    if(point != queue->end){ 
     point = point + sizeof(int*); 
     return point; 
    }else{ 
     return queue->data; 
    } 
} 

    queue_t* create_queue(int capacity){ 
     queue_t* fifo; 
     fifo = malloc(sizeof(queue_t)); 
     fifo->data = malloc((capacity) * sizeof(int*)); 
     fifo->end = fifo->data + (capacity*sizeof(int*)); 
     fifo->head = fifo->data; 
     fifo->tail = fifo->data; 
     fifo->cur_length = 0; 
     fifo->max_length = capacity; 
     return fifo; 
    } 

    void delete_queue(queue_t *queue){ 
     free(queue->data); 
     free(queue); 
    } 

    bool push_to_queue(queue_t *queue, void *data){ 
     int *temp = (int*) data; 
     //*(queue->tail) = *temp; 
     memcpy(queue->tail, temp, sizeof(int)); 
     free(data); 
     if(queue->max_length != queue->cur_length){ 
      queue->cur_length++; 
     } 

     queue->tail = increase(queue->tail, queue); 

     if(queue->tail == queue->head){ 
      queue->head = increase(queue->head, queue); 
     } 
     return true; 
    } 

    void* pop_from_queue(queue_t *queue){ 
     if(queue->cur_length == 0){ 
      return NULL; 
     } 
     int *item = malloc(sizeof(int*)); 
     //*item = *(queue->head); 
     memcpy(item, queue->head, sizeof(int)); 
     queue->head = increase(queue->head, queue); 
     queue->cur_length--; 
     return item; 
    } 
:ここ

typedef struct queue_t{ 
    int* data; 
    int* end; 
    int* head; 
    int* tail; 
    int max_length; 
    int cur_length; 
} queue_t; 

は、バッファ操作を管理するための私の方法です

これは、前述のバッファ操作の機能をテストするための主な方法です。
(私の関数が定義されているqueue.hがある)

#include "queue.h" 


void print_int(void* p){ 
    if(p != NULL){ 
     printf("%d\n", *((int*)p)); 
    } else { 
     printf("NULL\n"); 
    } 
} 

int main(){ 
    int n = 2; 
    int max = 10; 
    queue_t *q; 


    q = create_queue(n); 

    for(int i = 0; i<max;i++){ 
     int* p = malloc(sizeof(int)); 
     *p = i; 
     if(!push_to_queue(q, (void*)p)){ 
      free(p); 
      exit(101); 
     } 
    } 

    for(int i = 0;i<max;i++){ 
     void* p = pop_from_queue(q); 
     print_int(p); 
     free(p); 
    } 
    delete_queue(q); 

    return 0; 
} 

そして最後に、これは私のvalgrindの出力です:

==20293== HEAP SUMMARY: 
==20293==  in use at exit: 0 bytes in 0 blocks 
==20293== total heap usage: 15 allocs, 15 frees, 1,136 bytes allocated 
==20293== 
==20293== All heap blocks were freed -- no leaks are possible 
==20293== 
==20293== ERROR SUMMARY: 7 errors from 2 contexts (suppressed: 0 from 0) 
==20293== 
==20293== 1 errors in context 1 of 2: 
==20293== Invalid read of size 4 
==20293== at 0x40097C: pop_from_queue (queue.c:72) 
==20293== by 0x400713: main (main.c:30) 
==20293== Address 0x52030f0 is 16 bytes before a block of size 4 free'd 
==20293== at 0x4C2EDEB: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==20293== by 0x4008B8: push_to_queue (queue.c:51) 
==20293== by 0x4006D5: main (main.c:23) 
==20293== Block was alloc'd at 
==20293== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==20293== by 0x4006B5: main (main.c:21) 
==20293== 
==20293== 
==20293== 6 errors in context 2 of 2: 
==20293== Invalid write of size 4 
==20293== at 0x4008AB: push_to_queue (queue.c:50) 
==20293== by 0x4006D5: main (main.c:23) 
==20293== Address 0x52030d0 is 16 bytes after a block of size 16 alloc'd 
==20293== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==20293== by 0x4007FB: create_queue (queue.c:33) 
==20293== by 0x40069E: main (main.c:18) 
==20293== 
==20293== ERROR SUMMARY: 7 errors from 2 contexts (suppressed: 0 from 0) 

コードの尖った行は以下のとおりです。

72: memcpy(item, queue->head, sizeof(int)); 
50: memcpy(queue->tail, temp, sizeof(int)); 

ありがとうございます、私は誰かが私にここでやっている悪い練習は何ですか?/

+0

おそらく根本原因ではありませんが、私の目にはまだポップがあります。このint * item = malloc(sizeof(int *));は実際には意味がありません。 'item'は' int'を指しているので、指すバイト数は 'int * 'ではなく' int'のサイズでなければなりません。だから、ポインタを二重にチェックしたい、ポインタがどのように割り当てられているのか、最後にポインタが指し示すものに何がどのくらいコピーされたのかを確認したい。 – alk

+0

ありがとう、訂正されましたがエラーは持続します...他の割り当てでも同様にチェックします – shade254

答えて

関連する問題