Ich versuche, eine Implementierung von Ringpuffer in Array durchzuführen. Ich behalte meine Daten in der Struktur und verwalte sie mit wenigen Methoden wie Push, Pop usw. Das Programm ist mehr oder weniger funktional und verhält sich wie erwartet, jedoch habe ich in meinem Valgrind-Test Fehler festgestellt. Und ich bin nicht in der Lage herauszufinden, was mit meinem Code nicht stimmt. Obwohl es so aussieht, als würde die Verwaltung von Daten über Zeiger in meiner Struktur das entscheidende Problem darstellen. Ich wäre sehr dankbar, wenn mir jemand in die richtige Richtung zeigen könnte, denn ich bin an diesem Punkt wirklich verloren.Abrufen von Daten vom Zeiger in der Struktur "Ungültiges Lesen/Schreiben"
Dies ist, wie meine Struktur wie folgt aussieht:
typedef struct queue_t{
int* data;
int* end;
int* head;
int* tail;
int max_length;
int cur_length;
} queue_t;
Hier meine Methoden sind Pufferoperationen zu verwalten:
(kommentiert Code erzeugt so ziemlich die gleichen Fehler wie 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;
}
Dies ist meine Hauptmethode, um die Funktionalität der erwähnten Pufferoperationen zu testen:
(Queue.h ist, wo meine Funktionen definiert sind)
#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;
}
Und schließlich das ist mein valgrind Ausgabe:
==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)
Spitzcodezeilen sind:
72: memcpy(item, queue->head, sizeof(int));
50: memcpy(queue->tail, temp, sizeof(int));
Vielen Dank im Voraus, ich hoffe, jemand wird dazu in der Lage sein Zeig mir, was ist das für eine schlechte Übung, die ich hier mache:/
Vielleicht nicht die Wurzeln verursachen, aber immer noch zu meinem Auge knallt: Das 'int * item = malloc (sizeof (int *));' macht keinen Sinn. 'item' zeigt auf ein' int', also sollte die Anzahl der Bytes, auf die es zeigt, die Größe eines 'int' nicht von einem' int * 'haben. So wollen Sie Zeiger überprüfen, wie ihnen zugeordnet wird und was und wie viel schließlich kopiert wird, auf was sie zeigen. – alk
Vielen Dank, korrigiert, aber der Fehler bleibt bestehen ... Ich werde dies auch in anderen Zuordnungen überprüfen – shade254