0

我的程序是用 C 语言编写的,它是一个磁盘模拟器。我写完了它,当我注释掉我的测试程序的某些行时它会运行,但是我在取消注释的地方出现内存错误。我怀疑这是我的 char* 的。

我注释掉的那一行(以及程序崩溃的地方)是

free(buffer);

其中 buffer 是从磁盘读入的字节字符串的 char*。它最初使用 malloc 分配了 30 个字节。

char* buffer = (char *) malloc(sizeof(char) * 30);

在这里发布的内容太多了,所以我将把我正在编写/复制的部分放到 char* 中,希望有人能看到我做错了什么。

我不认为这太复杂了,我只是对 C 不够熟悉,可以识别明显的内存错误。

 // In the event of a cache miss:

 // block_buffer to pass to add_cache_entry
 char cMissBuffer[BLOCK_SIZE];

 // read content of block from disk 
 fread(cMissBuffer,sizeof(char),BLOCK_SIZE,diskEntity.pBlockStore);

 // add to cache
 if(1==add_cache_entry(i,cMissBuffer)) return 1;
 .
 .
 .
 // some of what is in add_cache_entry

 int add_cache_entry(int v, char *block_buffer)
 {
    // ...
    // construct a new queue element
    QueueElement *block_to_cache = (QueueElement*)malloc(sizeof(QueueElement));
    block_to_cache->blkidx = v;

    block_to_cache->content=(char*)malloc(BLOCK_SIZE);
    strcpy(block_to_cache->content,block_buffer);
// ...
 }

在测试中,BLOCK_SIZE 为 5,QueueElement 是一个 struct,content 是一个 char* 和 BLOCK_BYTES 的 info。

这是运行可执行文件(转储队列)的摘录...我认为缺少“\ 0”可能与该问题有关...

after adding cache entry (5):
DUMP:
BLOCK 5 FLAG:0 CONTENT:222220000000
BLOCK 4 FLAG:0 CONTENT:222220000000
BLOCK 3 FLAG:0 CONTENT:000000000000
BLOCK 2 FLAG:0 CONTENT:000000000000
BLOCK 1 FLAG:1 CONTENT:11100

我想我得到了额外的空间,因为 malloc 分配的空间比我需要的多,但我读到这是正常的。

有什么想法吗?

4

1 回答 1

3

该行为的一个可能原因是strcpy()要求源字符串以空值终止,这不是这里的情况,因为fread()不会为您附加空终止符(在这种情况下也不能fread()读取确切的缓冲区大小)。strcpy()还附加了一个空终止符,这意味着strcpy()调用肯定会超出block_to_cache->content缓冲区。

如果数据不用作 C 样式字符串memcpy(),请改为复制数据:

memcpy(block_to_cache->content, block_buffer, BLOCK_SIZE);

其他要点:

  • 检查 , 的返回值fread(),以确保它在尝试使用之前成功填充缓冲区。
  • 没有必要强制转换的返回值malloc()(请参阅Do I cast the result of malloc?)。
  • 检查返回值malloc()以确保内存分配成功。
  • sizeof(char)保证为 1,因此可以从 的参数中删除malloc()
于 2012-10-01T19:41:18.823 回答