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

问题描述 投票:1回答:2

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

#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;
}
c memory-management
2个回答
0
投票

正确的方法来优化内存使用?

暂时重复使用的缓冲区通常可以是慷慨的并且大小固定。

分配适当大小的内存量对于成员.username来说代码可能适用于数百万的struct Player

IOWs,使用分配代码的可变大小方面。如果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
投票

一些技巧:

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个字符,故意捣毁/破坏其他数据),这会导致巨大的安全漏洞。

© www.soinside.com 2019 - 2024. All rights reserved.