【问题标题】:Program efficiency, allocate memory for both read and write程序效率,为读写分配内存
【发布时间】:2021-03-22 13:03:50
【问题描述】:

我编写了一个简单的程序,我想知道我是否以一种有效的方式编写了该程序。程序打开一个文件进行读写,然后用pwrite写入(我不希望文件的偏移量随着写入而移动),并用pread读取文件。我只是想知道是否有必要像我一样分配两次内存。

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char const *argv[])
{
    char *write_buf = malloc(14), *read_buf = malloc(14);

    int fd = open("file", O_CREAT | O_RDWR, 0644); /* open a file called file */
    if (fd == -1) {
         perror("write");
         exit(-1); // Error, exit program
    }

    strcpy(write_buf, "Hello, World!"); /* copy string into write_buf */
    pwrite(fd, write_buf, strlen(write_buf), 0); /* pwrite (without moving file pointer) write_buf into fd (file) */
    pread(fd, read_buf, strlen(write_buf), 0); /* pread (without moving file pointer) into read_buf from fd (file) */

    close(fd);
    free(write_buf); free(read_buf);

    return 0;
}

【问题讨论】:

  • 不是没有必要。您可以读入与您写入的缓冲区相同的缓冲区。
  • 提示:不要像这样堆叠你的定义,它只会造成混乱。每个char *x = malloc() 应该在自己的行上。此外,14 应该是某个地方定义的常量,而不是随意打在那里。
  • 提示:不要使用strcpy(),使用strncpy()确保缓冲区有足够的空间容纳您的字符串。在 C 中,测试返回值 以检测错误非常重要。你几乎不会在这里做任何事情。 "Hello, World!" just 适合该缓冲区。如果您添加了另一个 !,您就会遇到缓冲区溢出错误,因此这种方法在灾难的边缘摇摇欲坠。
  • @Jabberwocky 但我需要先清除它,不是吗?
  • 您知道您可以将字符串写入文件,而不将其移动到缓冲区吗? const char input[]="Hallo World!"; ssize r=pwrite(fd,input,strlen(input),0); 之类的东西应该可以正常工作。

标签: c dynamic-memory-allocation memory-efficient


【解决方案1】:

这里有很多地方出了点问题,但在 C 中,有一点点错误是工作正常和一直崩溃之间的区别。清理它会导致:

int main(int argc, char const *argv[])
{
  const int BUFFER_SIZE = 1024;
  char *buf = malloc(BUFFER_SIZE);

  int fd = open("file", O_CREAT | O_RDWR, 0644);

  if (fd == -1) {
    perror("write");
    exit(-1);
  }

  // Here strncpy() can fail if the buffer is too small, so ensure
  // your buffer size is big enough for any reasonable cases. Test the
  // return value if you're not sure what the input size is going to be.
  strncpy(buf, "Hello, World!", BUFFER_SIZE);
  pwrite(fd, buf, strlen(buf), 0);
  
  // strlen() is the wrong tool here, you need the size of the buffer
  // itself, not the length of whatever's in it.
  pread(fd, buf, BUFFER_SIZE, 0);

  close(fd);

  // This wouldn't be necesssary if you had: char buf[BUFFER_SIZE]
  free(buf);

  return 0;
}

了解strlen()sizeof 之间的区别,以及如何在您的代码中始终如一地使用常量大小。

这里的原则是您想要更改一件事并让它正确地波及您的代码。

【讨论】:

  • 谢谢,我应该检查什么返回值?
  • 我认为没有必要检查每个电话
  • 任何可能返回错误的东西。在 YOLO 代码中你可以摆脱很多。在其他情况下,您可以合理地保证您永远不会出错,或者至少不会出现您可以处理的错误。如果您收到未知长度的未知用户数据,您必须更加小心。
  • 假设检查每一个电话是没有必要的,有时你会面临危险。对于像这样的一次性代码,你可以摆脱很多。如果这是关键内核代码,NO,您必须检查。
猜你喜欢
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多