自定义读取产生垃圾

  • 本文关键字:读取 自定义 c++
  • 更新时间 :
  • 英文 :


我正在实现自己的读取函数,该函数将内容从文件读取到缓冲区中。 它成功地读取了文件中的信息,但是当我打印出信息时,它有垃圾空字节"\00\"附加到输出。因此,当我阅读"嗨,那里"时,我阅读的输出可能是"hi\00\00\00th\00\00\00er\00e"我不知道是什么原因造成的,感谢任何帮助。我不确定它是否重要,但"\00"每次出现在 2 个字符之后。

bool FileRead(int ptrBuffer, int bufferSize, int fid)
{
  if (bufferSize == 0)
    {
     DEBUG('p', "Cannot read zero bytes.n");
     machine->WriteRegister(2, -2);
     return false;
    }
  char *buffer = (char *)malloc(sizeof(char *) * (bufferSize +1));
  DEBUG('p', "Attempting to read %d bytes from file %dn", bufferSize, fid);
  // Read bytes from the file.
  OpenFile* file = openFileTable[fid - FID_OFFSET];
  if (file == NULL) {
      DEBUG('p', "File does not exist!n");
      machine->WriteRegister(2, -4);
      return false;
  }
  file->Read(buffer, bufferSize + 1);
  int len = strlen(buffer);
  DEBUG('p', "Read string %s with len %dn", buffer, len);
  buffer[len] = '';
  strcpy(&machine->mainMemory[ptrBuffer], buffer);
  machine->WriteRegister(2, len-1);
  return true;
}

以下几行似乎非常可疑:

file->Read(buffer, bufferSize + 1);
int len = strlen(buffer);
buffer[len] = '';

在这里,您尝试使用strlen来获取读取的缓冲区的长度,该明确期望它传递的字符串被终止。然后,将缓冲区作为字符串终止。如果缓冲区一开始不包含终止符,则使用 strlen 函数将导致未定义的行为

Read函数很可能返回它已读取的长度(这是通常的(,这意味着如果它是值长度,则需要使用该值(并少读取一个字符(:

auto len = file->Read(buffer, bufferSize);
if (len > 0)
{
    buffer[len] = '';
    ... (the rest of the code) ...
}

此外,在尝试打印之前执行此操作终止。

您不会以 null 终止读取的字节,也不会忽略实际读取的字节数:

file->Read(buffer, bufferSize + 1);

应该是:

int nr = file->Read(buffer, bufferSize + 1);
if(nr > 0) {
  buffer[min(nr, bufferSize)] = '';

在行中:char *buffer = (char *)malloc(sizeof(char *) * (bufferSize +1));您正在尝试将缓冲区大小指针数分配给字符。

您真正想要分配的是:

char *buffer = (char *)malloc(sizeof(char) * (bufferSize +1));

或者更简单地说:

char *buffer = (char *)malloc(bufferSize + 1);

编辑:顺便说一句,不熟悉"OpenRead"类等,所以不确定这些读取在引擎盖下做什么等。不确定它是否有返回值。

另一件需要注意的事情是,假设 ->read 方法与预期中的任何方法一样,它以 null 终止字符串,那么 strlen 确实会给你字符串中的字节数。

您需要确保的是 strcpy 的目标有空间容纳缓冲区内容。更安全的副本可能是使用 strncpy(dst, src, len( 调用。

最新更新