在此板上搜索有關使用 C 將完整檔案讀入記憶體的資訊時,我遇到了以前從未見過的 fread() 用法。我試圖理解它。
我的問題是:
這里有什么名稱/術語嗎?
size_t used當添加到時會發生什么? freadchar *data如何認為這是有效void *ptr的?
我將把作者帖子中的代碼放在這里,我也會鏈接到帖子。不幸的是,該帖子已過時,已鎖定,并且我在這里沒有足夠的積分來發表評論,要求對其進行澄清。
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
/* Size of each input chunk to be
read and allocate for. */
#ifndef READALL_CHUNK
#define READALL_CHUNK 262144
#endif
#define READALL_OK 0 /* Success */
#define READALL_INVALID -1 /* Invalid parameters */
#define READALL_ERROR -2 /* Stream error */
#define READALL_TOOMUCH -3 /* Too much input */
#define READALL_NOMEM -4 /* Out of memory */
/* This function returns one of the READALL_ constants above.
If the return value is zero == READALL_OK, then:
(*dataptr) points to a dynamically allocated buffer, with
(*sizeptr) chars read from the file.
The buffer is allocated for one extra char, which is NUL,
and automatically appended after the data.
Initial values of (*dataptr) and (*sizeptr) are ignored.
*/
int readall(FILE *in, char **dataptr, size_t *sizeptr)
{
char *data = NULL, *temp;
size_t size = 0;
size_t used = 0;
size_t n;
/* None of the parameters can be NULL. */
if (in == NULL || dataptr == NULL || sizeptr == NULL)
return READALL_INVALID;
/* A read error already occurred? */
if (ferror(in))
return READALL_ERROR;
while (1) {
if (used READALL_CHUNK 1 > size) {
size = used READALL_CHUNK 1;
/* Overflow check. Some ANSI C compilers
may optimize this away, though. */
if (size <= used) {
free(data);
return READALL_TOOMUCH;
}
temp = realloc(data, size);
if (temp == NULL) {
free(data);
return READALL_NOMEM;
}
data = temp;
}
n = fread(data used, 1, READALL_CHUNK, in);
if (n == 0)
break;
used = n;
}
if (ferror(in)) {
free(data);
return READALL_ERROR;
}
temp = realloc(data, used 1);
if (temp == NULL) {
free(data);
return READALL_NOMEM;
}
data = temp;
data[used] = '\0';
*dataptr = data;
*sizeptr = used;
return READALL_OK;
}
鏈接:C 編程:如何將整個檔案內容讀入緩沖區
uj5u.com熱心網友回復:
當使用的 size_t 被添加到 char *data 時會發生什么,這如何被 fread 視為有效的 void *ptr?
在實踐中(*),指標只是一個數字,它參考(虛擬)記憶體中的地址。這里所做的是簡單的指標運算:您可以將一個整數添加到一個指標,這會增加它的值,所以如果您的指標指向地址 1000 并且您添加 20,它現在指向地址 1020。因為used總是位元組數到目前為止,您將這么多位元組指向data緩沖區。
但還有一件事:只有當指標的資料型別的大小為 1 位元組時(如 char (*) 那樣),這才有效。因為當您進行指標運算時,您不會將指標增加那么多位元組,而是增加資料型別大小的倍數,因此您最終總是指向陣列中元素的開頭,而不是陣列中的某個位置中間如果你正在處理int。即,如果你有int *xwhich 指向地址 1000,并且你這樣做了x = 20,那么x現在將指向地址 1080,這就是所在的x[20]位置。
fread 如何將其視為有效的 void *ptr?
考慮到“指標只是數字”,fread并不關心您是如何得出該指標值的。只要有有效的記憶體可以寫入,它就會很樂意接受你傳遞的任何內容。
(*) 假設只有凡人可以使用現代建筑。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/462099.html
