这是优化内存使用率的正确方法吗?

时间:2019-03-23 17:10:53

标签: c memory-management

我的目标是优化内存使用...在任何教程中我从未见过,这使我认为这不是正确的方法

#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;
}

2 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分:-1)

一些提示:

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个字符以上的内存,目的是故意破坏/破坏其他数据),这将导致巨大的安全漏洞。