Heim > Betrieb und Instandhaltung > Betrieb und Wartung von Linux > Detaillierte Erläuterung der Probleme mit der C-Sprachwarteschlange unter Linux

Detaillierte Erläuterung der Probleme mit der C-Sprachwarteschlange unter Linux

黄舟
Freigeben: 2017-06-07 09:56:05
Original
1817 Leute haben es durchsucht

Ich habe kürzlich ein Programm geschrieben, das die Warteschlangenoperation der C-Sprache unter dem Linux-System verwendet, daher hatte ich die folgende Frage
Das Folgende ist der Code der Warteschlange:
Diese Warteschlangen-Header-Datei

extern struct pqueue Que;

/*构造一个空队列*/
extern pQueue *InitQueue();

/*销毁一个队列*/
extern void DestroyQueue(pQueue *pqueue);

/*清空一个队列*/
extern void ClearQueue(pQueue *pqueue);

/*判断队列是否为空*/
extern int IsEmpty(pQueue *pqueue);

/*返回队列大小*/
extern int GetSize(pQueue *pqueue);

/*返回队头元素*/
extern PNode GetFront(pQueue *pqueue,char *pitem);

/*返回队尾元素*/
extern PNode GetRear(pQueue *pqueue,char *pitem);

/*将新元素入队*/
extern PNode InQueue(pQueue *pqueue,char *pitem);

/*队头元素出队*/
extern PNode OutQueue(pQueue *pqueue,char *pitem);
Nach dem Login kopieren

Das Folgende ist die Warteschlangenfunktion

struct pqueue Queue;		



	/*构造一个空队列*/

	pQueue *InitQueue()

	{

		pQueue *pqueue = (pQueue *)malloc(sizeof(Queue));

		if(pqueue!=NULL)

		{

			pqueue->front = NULL;

			pqueue->rear = NULL;

			pqueue->size = 0;

		}

		return pqueue;

	}



	/*销毁一个队列*/

	void DestroyQueue(pQueue *pqueue)

	{

		if(IsEmpty(pqueue)!=1)

			ClearQueue(pqueue);

		free(pqueue);

	}

	

	/*清空一个队列*/

	void ClearQueue(pQueue *pqueue)

	{

		while(IsEmpty(pqueue)!=1)

		{

			OutQueue(pqueue,NULL);

		}

	

	}

	

	/*判断队列是否为空*/

	int IsEmpty(pQueue *pqueue)

	{

		if(pqueue->front==NULL&&pqueue->rear==NULL&&pqueue->size==0)

			return 1;

		else

			return 0;

	}

	

	/*返回队列大小*/

	int GetSize(pQueue *pqueue)

	{

		return pqueue->size;

	}

	

	/*返回队头元素*/

	PNode GetFront(pQueue *pqueue,char *pitem)

	{

		if(IsEmpty(pqueue)!=1)

		{

			//pitem = pqueue->front->data;

		strcpy(pitem,pqueue->front->data);

		}

		return pqueue->front;

	}

	

	/*返回队尾元素*/

	

	PNode GetRear(pQueue *pqueue,char *pitem)

	{

		if(IsEmpty(pqueue)!=1)

		{

			//pitem = pqueue->rear->data;

		strcpy(pitem,pqueue->rear->data);

		}

		return pqueue->rear;

	}

	

	/*将新元素入队*/

	PNode InQueue(pQueue *pqueue,char *pitem)

	{

	//DBG0_PR("dbg QueueIn front=%d, rear=%d, count=%d\n", pqueue->front, pqueue->rear, pqueue->size);

		PNode pnode = (PNode)malloc(sizeof(Node));

		if(pnode != NULL)

		{

			strcpy(pnode->data, pitem);

			pnode->next = NULL;

	

			if(IsEmpty(pqueue))

			{

				pqueue->front = pnode;

			}

			else

			{

				pqueue->rear->next = pnode;

			}

			pqueue->rear = pnode;

			pqueue->size++;

		}

		return pnode;

	}

	

	/*队头元素出队*/

	PNode OutQueue(pQueue *pqueue,char *pitem)

	{

		PNode pnode = pqueue->front;

		if(IsEmpty(pqueue)!=1 && pnode!=NULL)

		{

			if(pitem!=NULL)

				strcpy(pitem,pnode->data);

			//pitem = pnode->data;

			pqueue->front = pnode->next;

			free(pnode);

			pqueue->size = pqueue->size - 1;

			if(pqueue->size == 0 ){

				pqueue->rear = NULL;

			}

		}

		return pqueue->front;

	}
Nach dem Login kopieren

Das Problem wird wie folgt beschrieben, wenn die Outque der Warteschlange verwendet wird:
Für die Warteschlange Bei der Operation ist die Warteschlangengröße 1 und bei der Operation zum Entfernen der Warteschlangengröße 0, und dann führt das Programm eine Schleife zurück, um die Warteschlangengröße zu bestimmen. Der Größenwert wird zu 393216. Ich weiß nicht, was passiert ist, nachdem er für a geändert wurde Lange Zeit.

Die Fehlermeldung ist so

*** glibc detected ***      double free or corruption (!prev):
Nach dem Login kopieren

Wenn jemand sie gesehen hat, antworten Sie mir bitte oder geben Sie mir ein paar Ideen. Ich habe das Gefühl, am Ende zu sein Ende. Danke! ! ! !

Auf Diskussion antworten (Lösung)

Kommentieren Sie einen Teil des Codes aus. Wenn das Problem verschwindet, liegt das Problem in der auskommentierter Code.

Drucken Sie den Wert der Größe in Echtzeit aus, um zu sehen, bei welchem ​​Schritt die Ausnahme aufgetreten ist

Nur ​​als Referenz

#ifndef __PQUEUE_H__
#define __PQUEUE_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_DATA_SIZE 256

typedef struct _node {
	char data[MAX_DATA_SIZE];
	struct _node* next;
} Node, *pNode;

typedef struct __pqueue {
	pNode front;
	pNode rear;
	int size;
} Queue, *pQueue;

/*构造一个空队列*/
extern pQueue InitQueue();

/*销毁一个队列*/
extern void DestroyQueue(pQueue pqueue);

/*清空一个队列*/
extern void ClearQueue(pQueue pqueue);

/*判断队列是否为空*/
extern int IsEmpty(pQueue pqueue);

/*返回队列大小*/
extern int GetSize(pQueue pqueue);

/*返回队头元素*/
extern int GetFront(pQueue pqueue, char *pitem);

/*返回队尾元素*/
extern int GetRear(pQueue pqueue, char *pitem);

/*将新元素入队*/
extern int InQueue(pQueue pqueue, char *pitem);

/*队头元素出队*/
extern int OutQueue(pQueue pqueue, char *pitem);

#endif /* __PQUEUE_H__ */

////////////////////////////////////////////////////////
#include "pqueue.h"		

#define err_log(fmt, ...) printf("[%s:%d]"fmt"\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define err_assert(con) { \
	if (!(con)) { \
		printf("[%s:%d]ASSERT>>> %s failed\n", __FUNCTION__, __LINE__, #con); \
		abort(); \
	} \
}
		

/*构造一个空队列*/
pQueue InitQueue()
{
	return (pQueue)calloc(1, sizeof(Queue));
}

/*销毁一个队列*/
void DestroyQueue(pQueue pqueue)
{
	err_assert(pqueue != NULL);
	
	if(!IsEmpty(pqueue))
		ClearQueue(pqueue);

	free(pqueue);
}

/*清空一个队列*/
void ClearQueue(pQueue pqueue)
{
	err_assert(pqueue != NULL);
	
	while (!IsEmpty(pqueue)) {
		OutQueue(pqueue, NULL);
	}
}

/*判断队列是否为空*/
int IsEmpty(pQueue pqueue)
{
	err_assert(pqueue != NULL);
	
	return !pqueue->size;
}

/*返回队列大小*/
int GetSize(pQueue pqueue)
{
	err_assert(pqueue != NULL);
	
	return pqueue->size;
}

/*返回队头元素*/
int GetFront(pQueue pqueue, char *pitem)
{
	err_assert(pqueue != NULL);
	
	if (IsEmpty(pqueue)) {
		return -1;
	}

	if (pitem) {
		err_assert(pqueue->front != NULL);
		strcpy(pitem, pqueue->front->data);
	}
	
	return 0;
}

/*返回队尾元素*/	
int GetRear(pQueue pqueue, char *pitem)
{
	err_assert(pqueue != NULL);
	
	if (IsEmpty(pqueue)) {
		return -1;
	}

	if (pitem) {
		err_assert(pqueue->rear != NULL);
		strcpy(pitem,pqueue->rear->data);
	}
	return 0;
}

/*将新元素入队*/
int InQueue(pQueue pqueue, char *pitem)
{
	err_assert(pqueue != NULL);
	
	pNode pnode = (pNode)calloc(1, sizeof(Node));
	if(NULL == pnode)  {
		return -1;
	}

	strcpy(pnode->data, pitem);
	pnode->next = NULL;
	if(IsEmpty(pqueue)) {
		pqueue->front = pnode;
	}
	else {
		pqueue->rear->next = pnode;
	}

	pqueue->rear = pnode;
	pqueue->size++;

	return 0;
}

/*队头元素出队*/
int OutQueue(pQueue pqueue,char *pitem)
{
	err_assert(pqueue != NULL);
	
	pNode pnode = pqueue->front;

	if (IsEmpty(pqueue)) {
		err_log("empty queue");
		return -1;
	}
	
	if (pitem)
		strcpy(pitem, pnode->data);

	pqueue->front = pnode->next;
	free(pnode);
	pqueue->size--;

	if (pqueue->size == 0 ){
		pqueue->rear = NULL;
	}

	return 0;
}

////////////////////////////////////////////////////////
#include "pqueue.h"		

int main(void)
{
	pQueue queue = NULL;

	queue = InitQueue();

	InQueue(queue, "I&#39;m ");
	InQueue(queue, "a ");
	InQueue(queue, "boy. ");

	while (!IsEmpty(queue)) {
		char buf[MAX_DATA_SIZE];
		if (OutQueue(queue, buf) < 0) {
			break;
		}
		printf("%s", buf);
	}
	
	printf("\n");
	DestroyQueue(queue);

	return 0;
}
Nach dem Login kopieren

Der Das Problem wurde gefunden, es handelt sich nicht um eine Warteschlange. Der Grund dafür ist, dass ich ein Zeichen* in einer Funktion mallociert und dann das von der Funktion zurückgegebene Zeichen* im Thread aufgerufen habe. Nachdem ich es verwendet habe, habe ich es freigegeben (am Ende der Funktion). ). Als Ergebnis wurde der obige Fehler gemeldet. Nachdem ich gesagt habe, dass es in Ordnung ist, weiß ich nicht, warum es nicht kostenlos sein kann die Funktion, in der Sie malloc schreiben

*** glibc erkannt *** doppelt frei oder Korruption (!prev):

Bezieht sich normalerweise auf die Bedienung eines freigegebenen Objekts, wie zum Beispiel:

1 wurde freigegeben, aber das Objekt, auf das der Zeiger zeigt, wird erneut bedient.

2. Ein bestimmtes dynamisch zugewiesenes Objekt im Multithreading wird von zwei Threads gleichzeitig verwendet. Ein Thread gibt das Objekt frei, während der andere Thread das Objekt weiterhin betreibt.

Fügen Sie eine Thread-Synchronisierung hinzu und es sollte kein Problem geben

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Probleme mit der C-Sprachwarteschlange unter Linux. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage