[英]Is this the right way to optimize memory usage?
我的目標是優化內存使用...在任何教程中我從未見過,這使我認為這不是正確的方法
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Player {
char* username;
int hp;
int mp;
};
int main(void) {
struct Player test, *p = &test;
p->username = (char*)malloc(50 * sizeof(char));
scanf("%s", p->username);
p->username = realloc(p->username, (strlen(p->username) + 1) * sizeof(char));
printf("%s", p->username);
return 0;
}
優化內存使用率的正確方法?
臨時重用的緩沖區通常可以很慷慨並且大小固定。
分配合適的尺寸量的內存是有道理的成員.username
的代碼可能是數以百萬計的struct Player
。
IOW,將分配用於代碼的可變大小方面。 如果struct Player
適用於2人國際象棋,則char username[50]
大小有意義。 對於多玩家宇宙, char *
是有意義的。
而不是兩次調用*alloc()
而是考慮單個大小合適的調用。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// Reasonable upper bound
#define USERNAME_SIZEMAX 50
struct Player {
char* username;
int hp;
int mp;
};
int main(void) {
puts("Enter user name");
// Recommend 2x - useful for leading/trailing spaces & detecting excessive long inputs.
char buf[USERNAME_SIZEMAX * 50];
if (fgets(buf, sizeof buf, stdin) == NULL) {
puts("No input");
} else {
trim(buf); // TBD code to lop off leading/trailing spaces
if (!valid_name(buf)) { // TBD code to validate the `name`
printf("Bad input \"%s\"\n", buf);
} else {
struct Player test = { 0 }; // fully populate
test.username = malloc(strlen(buf) + 1);
// Maybe add NULL check here
strcpy(test.username, buf);
// Oh happy day!
printf("%s", p->username);
return EXIT_SUCCESS;
}
}
return EXIT_FAILURE;
}
一些技巧:
a)示例代碼太小無關緊要
b)永遠不要將malloc()
用於您永遠想要的一種。 相反,預分配(例如,作為全局變量)或(如果足夠小)使用局部變量來避免malloc()
的開銷。 例如:
int main(void) {
struct Player test, *p = &test;
char userName[50];
p->username = userName;
c)不要將數據散布到整個地方。 您希望所有數據都在同一位置(在最少的緩存行中,並且同時使用的數據段盡可能地彼此靠近)。 一種方法是組合多個項目。 例如:
struct Player {
char username[50];
int hp;
int mp;
};
int main(void) {
struct Player test, *p = &test;
d)如果某件事最多占用50個字符; 不要費心使用realloc()
來浪費CPU時間並可能浪費更多的內存。 不要忘記, malloc()
和realloc()
的內部代碼會將元數據添加到每個分配的內存中,這可能會花費額外的16個字節或更多。
一般來說; 為了提高性能,應完全避免使用malloc()
和realloc()
(以及new()
和...)(尤其是對於較大的程序)。 他們將數據“隨機”分布到各處,並破壞了獲得良好本地性的任何希望(這對於最小化多個非常昂貴的事情很重要-緩存未命中,TLB未命中,頁面錯誤,交換空間使用等)。
注意: scanf()
和gets()
也應被禁止。 它們沒有提供防止緩沖區溢出的方法(例如,當只有50個字符分配足夠的內存時,用戶故意提供50個以上的字符,目的是故意破壞/破壞其他數據),這將導致巨大的安全漏洞。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.