最近写程序用到了Linux系统下C语言的队列操作,于是有了下面一个问题
下面是队列的代码:
这个队列头文件
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);
下面是队列函数
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;
}
问题在使用队列的outque时,描述如下:
入队操作,队列大小size为1,出队操作队列大小操作为0,然后程序循环一圈回来再判断队列大小,size值变成了393216,改了半天也不知道怎么回事,
提示错误是这样的
*** glibc detected *** double free or corruption (!prev):
如果哪位大虾看见了,求解答或者给个思路,感觉自己已经进了死胡同了,跪谢!!!!
回复讨论(解决方案)
注释掉一部分代码,如果问题消失,问题就出在注释掉的代码里
实时打印size的值,看在哪一步出现的异常
仅供参考
#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'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; }
找到问题了,不是队列的原因,我在一个函数里面malloc了一个char*,然后在线程中调用该函数返回的这个char*,用完之后free(在该功能尾部),结果就报上面的错误了,我注释掉这句free之后就没事了,不解的是不知道为啥不能free free应该放在你写malloc的函数里面 *** glibc detected *** double free or corruption (!prev): 2.多线程中某一动态分配的对象同时被两个线程使用,一个线程释放了该对象,而另一线程继续对该对象进行操作。 加个线程同步 应该就没有问题
通常是指操作已释放的对象,如:
1.已释放对象,却再次操作该指针所指对象。
Atas ialah kandungan terperinci Linux下关于C语言队列问题的详解. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Mod penyelenggaraan memainkan peranan utama dalam pengurusan sistem Linux, membantu membaiki, menaik taraf dan perubahan konfigurasi. 1. Masukkan mod penyelenggaraan. Anda boleh memilihnya melalui menu grub atau menggunakan arahan "SudosystemCtlisolaterscue.target". 2. Dalam mod penyelenggaraan, anda boleh melakukan pembaikan sistem fail dan operasi kemas kini sistem. 3. Penggunaan lanjutan termasuk tugas -tugas seperti menetapkan semula kata laluan root. 4. Kesilapan umum seperti tidak dapat memasukkan mod penyelenggaraan atau memasang sistem fail, boleh diperbaiki dengan memeriksa konfigurasi grub dan menggunakan arahan FSCK.

Masa dan alasan untuk menggunakan mod penyelenggaraan Linux: 1) Apabila sistem bermula, 2) apabila melakukan kemas kini sistem utama atau peningkatan, 3) apabila melakukan penyelenggaraan sistem fail. Mod penyelenggaraan menyediakan persekitaran yang selamat dan terkawal, memastikan keselamatan dan kecekapan operasi, mengurangkan kesan kepada pengguna, dan meningkatkan keselamatan sistem.

Perintah yang tidak diperlukan di Linux termasuk: 1.LS: Kandungan Direktori Senarai; 2.CD: Tukar direktori kerja; 3.MKDIR: Buat direktori baru; 4.RM: Padam fail atau direktori; 5.CP: Salin fail atau direktori; 6.MV: Pindahkan atau menamakan semula fail atau direktori. Perintah ini membantu pengguna menguruskan fail dan sistem dengan cekap dengan berinteraksi dengan kernel.

Di Linux, pengurusan fail dan direktori menggunakan arahan LS, CD, MKDIR, RM, CP, MV, dan Pengurusan Kebenaran menggunakan arahan CHMOD, Chown, dan CHGRP. 1. Perintah pengurusan fail dan direktori seperti senarai terperinci LS-L, MKDIR-P membuat direktori secara rekursif. 2. Perintah Pengurusan Kebenaran seperti Kebenaran Fail Set Chmod755File, ChownUserFile mengubah pemilik fail, dan ChGRPGroupFile Change File Group. Perintah ini berdasarkan struktur sistem fail dan sistem pengguna dan kumpulan, dan mengendalikan dan mengawal melalui panggilan sistem dan metadata.

Maintenancemodeinlinuxisaspecialbootenvironmentforcriticalsystemmaintenancetasks.itallowsadministratorstoperformTaskslikeresettingPasswords, RepairingFilesystems, andRecoveringFrombootfailureSinaminiMinalenvirenment.ToentermoDeDenance.ToentermodeShoode.ToentermodeShoode.ToentermodeShoode.ToentermoDeShoode.ToentermodeShoode.ToentermodeShoode.ToentermodeShoode.Toentermode

Komponen teras Linux termasuk kernel, sistem fail, shell, pengguna dan ruang kernel, pemandu peranti, dan pengoptimuman prestasi dan amalan terbaik. 1) Kernel adalah teras sistem, menguruskan perkakasan, memori dan proses. 2) Sistem fail menganjurkan data dan menyokong pelbagai jenis seperti Ext4, BTRFS dan XFS. 3) Shell adalah pusat arahan untuk pengguna untuk berinteraksi dengan sistem dan menyokong skrip. 4) Ruang pengguna berasingan dari ruang kernel untuk memastikan kestabilan sistem. 5) Pemandu peranti menghubungkan perkakasan ke sistem operasi. 6) Pengoptimuman prestasi termasuk konfigurasi sistem penalaan dan mengikuti amalan terbaik.

Lima komponen asas sistem Linux adalah: 1. Kernel, 2. Perpustakaan Sistem, 3. Utiliti Sistem, 4. Antara Muka Pengguna Grafik, 5. Aplikasi. Kernel menguruskan sumber perkakasan, Perpustakaan Sistem menyediakan fungsi yang telah dikompilasi, utiliti sistem digunakan untuk pengurusan sistem, GUI menyediakan interaksi visual, dan aplikasi menggunakan komponen ini untuk melaksanakan fungsi.

Mod penyelenggaraan Linux boleh dimasukkan melalui menu grub. Langkah -langkah tertentu ialah: 1) Pilih kernel dalam menu grub dan tekan 'E' untuk mengedit, 2) Tambah 'Single' atau '1' pada akhir garis 'Linux', 3) Tekan Ctrl X untuk memulakan. Mod penyelenggaraan menyediakan persekitaran yang selamat untuk tugas seperti pembaikan sistem, penetapan semula kata laluan dan peningkatan sistem.


Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

mPDF
mPDF ialah perpustakaan PHP yang boleh menjana fail PDF daripada HTML yang dikodkan UTF-8. Pengarang asal, Ian Back, menulis mPDF untuk mengeluarkan fail PDF "dengan cepat" dari tapak webnya dan mengendalikan bahasa yang berbeza. Ia lebih perlahan dan menghasilkan fail yang lebih besar apabila menggunakan fon Unicode daripada skrip asal seperti HTML2FPDF, tetapi menyokong gaya CSS dsb. dan mempunyai banyak peningkatan. Menyokong hampir semua bahasa, termasuk RTL (Arab dan Ibrani) dan CJK (Cina, Jepun dan Korea). Menyokong elemen peringkat blok bersarang (seperti P, DIV),

SecLists
SecLists ialah rakan penguji keselamatan muktamad. Ia ialah koleksi pelbagai jenis senarai yang kerap digunakan semasa penilaian keselamatan, semuanya di satu tempat. SecLists membantu menjadikan ujian keselamatan lebih cekap dan produktif dengan menyediakan semua senarai yang mungkin diperlukan oleh penguji keselamatan dengan mudah. Jenis senarai termasuk nama pengguna, kata laluan, URL, muatan kabur, corak data sensitif, cangkerang web dan banyak lagi. Penguji hanya boleh menarik repositori ini ke mesin ujian baharu dan dia akan mempunyai akses kepada setiap jenis senarai yang dia perlukan.

VSCode Windows 64-bit Muat Turun
Editor IDE percuma dan berkuasa yang dilancarkan oleh Microsoft

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Versi Mac WebStorm
Alat pembangunan JavaScript yang berguna
