在C代碼,我有一個大型的C代碼,32位計算機上工作正常,但無法在64臺機器與的glibc損壞的雙向鏈表的錯誤,同時運行64位機
*** glibc detected *** ./XXX.exe: corrupted double-linked list:
錯誤。
我已經運行Valgrind並使用打印語句準確查明錯誤來自哪裏,但對修復無能爲力。 實際代碼非常大,但我在這裏給出相關部分。希望有人能幫我解決它。 實際的錯誤從Buf_Close()
模塊來它嘗試釋放Buf_elm_p p
作爲if (p != NULL) free(p);
這些功能的主代碼調用的,我只是在這裏給這個因爲錯誤是在這裏的某個地方。從主代碼的調用順序是:
1. Buf_Init 2. Buf_New_p 3. Buf_Close
Buf_bf_p
Buf_Init(size_t elm_size,
int nelm_buf,
long nbuf)
/*******************************************************************************
!C
!Description: Buf_Init (buffer initialize) initializes buffer data structures
and buffers.
!Input Parameters:
elm_size element size (bytes)
nelm_buf number of elements per buffer
nbuf number of buffers
!Output Parameters:
(returns) pointer to the buffer data structure
or NULL for an error return
*****************************************************************************/
{
Buf_bf_p bf;
long buf_size;
long ibuf;
/* Calculate buffer size and check */
buf_size = ((long) elm_size) * nelm_buf;
/*Allocate the buffer data structure */
if ((bf = (Buf_bf_p) malloc(sizeof(Buf_bf_t))) == NULL)
{Buf_Error(&BUF_NOMEMORY, "Init"); return NULL;}
bf->key = BUF_KEY;
bf->elm_size = elm_size;
bf->nelm_buf = nelm_buf;
bf->nbuf = nbuf;
bf->buf_size = buf_size;
bf->fp = NULL;
bf->access = NO_FILE;
bf->nbuf_alloc = 1;
bf->ibuf_end = 0;
bf->ibuf_newest = 0;
bf->ibuf_oldest = 0;
bf->nelm = 0;
/* Allocate the buffer status data structure */
bf->nbstat = max(NBSTAT_START, bf->nbuf + 1);
if ((bf->bstat = (Buf_bstat_t *)
malloc(bf->nbstat * sizeof(Buf_bstat_t))) == NULL)
{Buf_Error(&BUF_NOMEMORY, "Init"); return NULL;}
/* Allocate the first buffer */
bf->bstat[0].loc = MEM_ONLY;
if((bf->bstat[0].buf_p = (Buf_elm_p) malloc(bf->buf_size)) == NULL)
{ Buf_Error(&BUF_NOMEMORY, "Init");
return NULL;
}
else
{
/* initialize */
memset(bf->bstat[0].buf_p, '\0', bf->buf_size);
}
bf->bstat[0].newer = -1;
bf->bstat[0].older = -1;
/* Initialize the rest of the buffer status array */
printf("bf->nbstat %d\n", bf->nbstat);
for (ibuf = 1; ibuf < bf->nbstat; ibuf++) {
bf->bstat[ibuf].loc = NOT_ALLOC;
bf->bstat[ibuf].buf_p = NULL;
bf->bstat[ibuf].newer = -1;
bf->bstat[ibuf].older = -1;
bf->bstat[ibuf].initialized = 1;
}
return bf;
}
Buf_elm_p
Buf_New_p(Buf_bf_p bf,
long *ielm)
/*******************************************************************************
!C
!Description: Buf_New_p (new buffer element pointer) returns a memory
location and element number of a new element; elements are number
sequentially as they are allocated.
!Input Parameters:
bf pointer to the buffer data structure
!Output Parameters:
ielm new element number
(returns) pointer to memory location of new element
or NULL for error
!Notes:
1. 'Buf_Init' must be called before this routine to initialize
the buffer data structure.
2. If there is no more space in memory and disk write access is allowed,
the oldest buffer is written to disk and the memory is re-used.
3. If the file is opened with 'read only' access this routine will return
an error.
!END
******************************************************************************/
{
long ibuf, jelm, jbuf, kbuf;
long nbuf_cmplt;
Buf_elm_p p;
long dsk_loc, eof_loc;
/* New element number/location */
*ielm = bf->nelm++;
ibuf = *ielm/bf->nelm_buf;
jelm = *ielm % bf->nelm_buf;
/* Are we at the past the end of the last buffer? */
if (ibuf > bf->ibuf_end) {
if (ibuf != (bf->ibuf_end + 1))
{Buf_Error(&BUF_BADBUF, "New_p"); return NULL;}
/* Re-allocate buffer status data structure if not large enough */
if(ibuf >= bf->nbstat)
{
bf->nbstat += min(bf->nbstat, MAX_NEW_NBSTAT);
if((bf->bstat = realloc(bf->bstat, bf->nbstat * sizeof(Buf_bstat_t)))
== NULL)
{ Buf_Error(&BUF_NOMEMORY, "New_p");
return NULL;
}
}
if (bf->nbuf_alloc < bf->nbuf || bf->access == NO_FILE) {
/* Allocate a new buffer */
if((p = (Buf_elm_p) malloc(bf->buf_size)) == NULL)
{ Buf_Error(&BUF_NOMEMORY, "New_p");
return NULL;
}
else
{
/* initialize */
memset(p, '\0', bf->buf_size);
}
bf->nbuf_alloc++;
if (bf->nbuf < bf->nbuf_alloc) bf->nbuf = bf->nbuf_alloc;
} else {
/* Re-use an existing buffer */
/* Get the oldest buffer */
jbuf = bf->ibuf_oldest;
/* Delete oldest buffer from old/new pointer list */
p = bf->bstat[jbuf].buf_p;
bf->ibuf_oldest = bf->bstat[jbuf].newer;
bf->bstat[bf->ibuf_oldest].older = -1;
bf->bstat[jbuf].buf_p = NULL;
bf->bstat[jbuf].older = -1;
bf->bstat[jbuf].newer = -1;
bf->bstat[jbuf].initialized = 1;
}
/* Put current buffer in old/new pointer list */
bf->bstat[ibuf].loc = MEM_ONLY;
bf->bstat[ibuf].buf_p = p;
bf->bstat[ibuf].older = bf->ibuf_newest;
bf->bstat[ibuf].newer = -1;
bf->bstat[ibuf].initialized = 1;
bf->ibuf_end = ibuf;
bf->bstat[bf->ibuf_newest].newer = ibuf;
bf->ibuf_newest = ibuf;
}
/* Calculate pointer to memory location of element */
p = (unsigned char *) bf->bstat[ibuf].buf_p + (jelm * bf->elm_size);
return p;
}
int
Buf_Close(Buf_bf_p bf)
/*******************************************************************************
!C
!Description: Buf_Close (buffer cache file close) writes the remainder of the
cache to the disk cache file and closes the file and frees memory of the
buffer data structure and buffers.
!Input Parameters:
bf pointer to the buffer data structure
Notes:
1. 'Buf_Create' or 'Buf_Open' must be called before this routine to open
the file.
!END
*****************************************************************************/
{
int i;
long dsk_loc;
logical_t cmplt_flag;
/* int b; */
Buf_elm_p p;
long ibuf, nelm_wrt;
int nb;
unsigned char header[HEADER_SIZE];
/* Write remaining buffers which are still only in memory */
for (ibuf = 0; ibuf < (bf->ibuf_end + 1); ibuf++)
/* for (ibuf = 0; ibuf < (bf->ibuf_end); ibuf++)*/{
p = bf->bstat[ibuf].buf_p;
/* Free the buffer memory */
**THIS FOLLOWING LINE IS WHERE THE ERROR IS COMING FROM**
**VALGRIND SHOWS `Conditional jump or move depends on uninitialised value(s)` ERROR**
**BUT AM NOT SURE HOW `p` is coming out to be uninitialized`**
if (p != NULL) free(p);
}
/* Free the buffer status memory */
free(bf->bstat);
/* Free the buffer cache data structure */
bf->fp = (FILE *)NULL;
bf->key = 0;
free(bf);
printf("buf here 5\n");
return BUF_NORMAL;
}
如果它在32位機器上工作正常,而不是在64位機器上,問題可能出現在你的代碼中,當然不在glibc中。你用32位的valgrind運行它嗎?或者也許你在指針算術的某個地方有問題(假設指針是32位寬)? –
是的,我知道這個問題在本身的某個地方,而不是glibc。此代碼最初是爲32位機器而設計的,我的感覺是可能需要做一些64位特定更改,而這些更改我不確定。 – srsci