想象一下這段簡單的代碼。在這里我分配了太多記憶體,我只想保留正確數量的位元組(例如通過網路發送)。
char src[100];
// Some code that only fills the buffer with 20 bytes
size_t sz = 20;
char dest[sz];
memcpy(dest, src, sz);
有沒有比使用 memcpy 更好的方法來做到這一點?
uj5u.com熱心網友回復:
在這里我分配了太多記憶體,我只想保留正確數量的位元組(例如通過網路發送)。
您無需調整記憶體大小即可發送正確的數量。fwrite需要您的元素有多大以及要發送多少。也許您總是使用緩沖區的大小來確定要發送的內容fwrite(src, size(src), 1, fp);。
相反,只發送您需要的內容。
// Only send the first 20 bytes of src.
fwrite(src, 20, 1, fp);
我實際上需要優化,因為我正在使用資源受限 (IoT) 設備。
您沒有節省任何記憶體,而是使用了更多記憶體。
因為你使用的是自動記憶src,直到塊結束。如果您復制src到dest您使用的是 120 位元組而不是 100。
uj5u.com熱心網友回復:
OP的代碼還可以,當編譯器支持變長陣列并且陣列需求沒有增長時。
char src[100];
size_t sz = 20;
char dest[sz]; // VLA
// memcpy(dest, src, sz);
memcpy(dest, src, sizeof dest); // Better when not a char array
在 C 中,一旦定義了陣列,它的大小就不能改變。所以 src[]必須保留 100 個元素,但dest[]可能會有所不同。
替代方案:通過*alloc()和朋友分配記憶體。
size_t sz = 100;
char *src = malloc(sizeof *src * sz);
if (src == NULL) Handle OutOfMemory();
sz = 20;
char *src_new = realloc(src, sizeof *src_new * sz);
if (src_new == NULL) Handle OutOfMemory();
src = src_new;
// memcpy() not needed as copying done by realloc()
// With a size increase, new elements are indeterminate.
free(src);
src = NULL;
第三種方法是在定義陣列之前做更多的作業并確定所需的大小。
int size = snprintf(NULL, 0, "%s %g %d", some_string, some_double, some_int);
assert(size >= 0);
char s[size 1u];
size = snprintf(s, sizeof s, "%s %g %d", some_string, some_double, some_int);
assert(size >= 0 && (unsigned) size < sizeof s);
uj5u.com熱心網友回復:
如果您的物件具有靜態或自動存盤類,則其大小無法在運行時更改。
有沒有比使用 memcpy 更好的方法來做到這一點?
memcpynovadays 是復制資料的最有效方式。現代編譯器非常了解這個函式,通常用行內的高效代碼替換對它的呼叫。
示例:https : //godbolt.org/z/1GKea7Mon
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/331923.html
標籤:C
上一篇:資料型別范圍的真正含義是什么?
下一篇:Ghidra是否誤解了函式呼叫?
