【问题标题】:malloc problem?malloc问题?
【发布时间】:2011-02-23 18:53:29
【问题描述】:

您好,我使用 malloc() 生成这样的缓冲区,其中缓冲区是 char*

buffer = (char*)malloc(chunksize+1);
  for (k = 0; k < chunksize; k++) {
    buffer[k] = (char) (j+k);
  }

但是,在调试器中,我可以看到缓冲区 [3] 例如是我写入的字符,但缓冲区缓冲区是空的(很多空格)。但是我第二次在free(buffer)之后在缓冲区中写东西,它显示了我第一次写的内容,并覆盖了它。谁能告诉我为什么?谢谢!!

【问题讨论】:

  • j 是什么? chunksize 是什么?你真的说“在 free(buffer) 之后在缓冲区中写东西”?
  • 对不起我的错。它在一个循环中,在循环结束时释放缓冲区,但我每次在写之前都会做 malloc,就像显示的代码一样
  • 不要做这两个演员。至少它们是多余的,第一个甚至可能隐藏诸如忘记包含原型之类的问题。
  • 不应该是malloc((chunksize+1)*sizeof(char))吗? (我不知道 C,但这看起来不对。)
  • sizeof(char) 始终为 1,因此放弃乘以 1 的无意义部分。

标签: c memory malloc


【解决方案1】:

一般来说,malloc 实现的工作原理是从操作系统获取大量内存,然后在您请求缓冲区时对其进行子分配。这是因为从操作系统获取内存相对较慢。

作为一项安全措施,您的操作系统将提供malloc 空白内存(充满 0 或其他一些重复值)。您不希望一个进程能够读取不相关进程的剩余部分。

但是,malloc 没有这样的问题,因为它只从该块服务到一个进程。您是否可以看到自己的遗物(至少不能从安全 POV 中看到)并不重要。

所以发生的事情是您分配了一个缓冲区,并且最初看到它是空白的。然后你释放了它并请求“另一个”缓冲区,而 malloc 恰好再次将相同的内存交给你,这次包含你留在其中的值。

两次获得相同内存的这种“巧合”并非不太可能,因为malloc 有充分的理由尽可能重用最近使用的内存 - 它更有可能在缓存中。

您可能认为这对您来说无关紧要,因为通常您不会从新分配的内存中读取。但这对malloc 很重要,因为通常 malloc 将自己的内务数据保存在缓冲区附近。从缓存中清除内存是否会产生相关成本也可能很重要 - 如果您可能被“诱骗”一遍又一遍地重用相同的内存,那么这种情况发生的情况就会减少。

【讨论】:

  • 谢谢。但是为什么当我从调试器检查缓冲区时没有写入字符?我打算立即将缓冲区写入文件。当我从文件中读取内容时,我得到很多“32”,即空格。但第二次,它表现正常。
  • @user512853:嗯,我可能误解了这个问题。我以为您的意思是您在循环执行时看到了空白内存,并用您的值(jj+1 等)覆盖。实际的空格字符(即 ASCII 32),与在调试内存视图中显示为空白的不可打印字符相反,对于未初始化的内存来说听起来不太可能。当您写入文件时,您是否确定写入与您填写的相同的块大小,并且从相同的地址开始?在调用 fwrite 之前检查内存的样子。
  • 我生成缓冲区,然后将缓冲区写入文件,释放缓冲区,再次 malloc 并重复前面的步骤。稍后,我将文件读取到缓冲区并比较内容是否与我之前写的相同,第一个块已满 32,其他块是正确的。
  • 当我检查内存时,调试器的行为很奇怪。例如,我可以看到 buffer[3] 是我写入的字符,但缓冲区中充满了空格
【解决方案2】:

一个问题可能是您尝试使用printf 或等效项打印您的char 缓冲区?你错过了分配

buffer[chunksize] = 0;

所以你的缓冲区没有很好地终止。它背后可能有任何东西,例如'\r'

另一方面,如果buffer 不代表您的字符串,最好使用不同的基本类型,可能是unsigned char

【讨论】:

  • 应该是buffer[chunksize] = '\0';。尽管它们可能具有相同的按位表示,但当您使用适当的文字时,您的意图会更加清晰。
  • 这只是一个品味问题。 '\0' 只不过是 0 的另一个名称。我更赞成对所有初始化使用相同的0
  • 空字符串:buffer[0] = '\0';
【解决方案3】:

您的代码是正确的。如果您担心会覆盖一些坏内存,则问题可能出在您未显示的代码的某些部分。例如,如果 buffer 是指向非字符数组的指针,在这种情况下,您使用的 pointer arithmetic 将导致错误的内存访问(损坏)。您可以参考以下程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ()
{
  const size_t chunksize = 15;
  size_t k;
  char *buffer;

  buffer = malloc (chunksize + 1);
  memset (buffer, 0, chunksize + 1);

  for (k = 0; k < chunksize; ++k)
    {
      buffer[k] = '0' + (char)k + 49;
    }

  for (k = 0; k < chunksize; ++k)
    {
      printf ("%lu = %c\n", k, buffer[k]);
    }

  free (buffer);

  return 0;
}

输出:

0 = a
1 = b
2 = c
3 = d
4 = e
5 = f
6 = g
7 = h
8 = i
9 = j
10 = k
11 = l
12 = m
13 = n
14 = o

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-26
    • 2018-07-06
    • 2011-02-17
    相关资源
    最近更新 更多