不一致的malloc内存损坏

时间:2015-11-20 17:43:54

标签: c pointers memory memory-management malloc

我目前正在编写一种方法,该方法从已分配的内存块中读取并从某个偏移量打印出其内容,直到指定的大小,这两个内容都作为参数传递。我正在使用char指针来完成此任务,但在行

周围不断收到malloc错误
char *content = (char *)malloc(size+1);

方法代码:

int file_read(char *name, int offset, int size)
{
    //First find file and its inode, if existing
    int nodeNum = search_cur_dir(name);
    if(nodeNum < 0) {
            printf("File read error: file does not exist\n");
            return -1;
    }

    //Size check, to avoid overflows/overreads
    if(offset > inode[nodeNum].size || size > inode[nodeNum].size || (offset+size) > inode[nodeNum].size)   {
            printf("File read error: offset and/or size is too large\n");
            return -1;
    }

    int i, read_size, track_size = size, content_offset = 0;
    int target_block = offset / BLOCK_SIZE; //Defined as constant 512
    int target_index = offset % BLOCK_SIZE;


    char *raw_content = (char *)malloc(inode[nodeNum].size+1);
    printf("check1\n"); //Debug statment

    for(i = target_block; i < (inode[nodeNum].blockCount-(size/BLOCK_SIZE)); i++)   {
            disk_read(inode[nodeNum].directBlock[i], raw_content+content_offset);
            content_offset += BLOCK_SIZE;
    }

    printf("check2\n"); //Debug statment
    char *content = (char *)malloc(size+1);

    memcpy(content, raw_content+target_index, size);
    printf("%s\n", content);
    free(raw_content);
    free(content);
    return 0;

}

和disk_read的代码:

char disk[MAX_BLOCK][BLOCK_SIZE]; //Defined as 4096 and 512, respectively
int disk_read(int block, char *buf)
{
                if(block < 0 || block >= MAX_BLOCK) {
                                printf("disk_read error\n");
                                return -1;
                }
                memcpy(buf, disk[block], BLOCK_SIZE);

                return 0;
}

节点

的结构
typedef struct {
                TYPE type;
                int owner;
                int group;
                struct timeval lastAccess;
                struct timeval created;
                int size;
                int blockCount;
                int directBlock[10];
                int indirectBlock;
                char padding[24];
} Inode; // 128 byte

使用此方法时出现的错误是内存损坏

*** glibc detected *** ./fs_sim: malloc(): memory corruption (fast): 0x00000000009f1030 ***

现在奇怪的部分是,首先这只发生在我使用该方法几次之后 - 对于前两次或三次尝试它将起作用然后发生错误。例如,这是一个示例测试运行:

% read new 0 5
z12qY

% read new 0 4
z12q

% read new 0 3
*** glibc detected *** ./fs_sim: malloc(): memory corruption (fast): 0x00000000009f1030 ***

更奇怪的是,当我发表评论

时,这个错误就完全消失了
free(raw_content);
free(content);

即便这样也会占用内存。我已经读过以前关于malloc内存损坏的帖子,并且理解这通常是由于覆盖内存边界或分配空间,但我无法看到我可以做到这一点。我已经尝试了malloc的其他大小,当我注释掉释放两个指针的行时,这些大小产生了最好的结果。有谁看到我可能会失踪?为什么这种情况发生得如此不一致?

1 个答案:

答案 0 :(得分:1)

代码为字符和空字符分配空间,但不保证在以字符串形式打印之前,数组以空字符终止。

char *content = (char *)malloc(size+1);
memcpy(content, raw_content+target_index, size);

// add
content[size] = '\0';

printf("%s\n", content);

也可能是其他问题。

[编辑]

OP代码容易出错,并依赖于inode[]来获得相干值(.blockCount . size)。通过确定循环计数并按该计数分配来澄清和简化。

int loop_count = (inode[nodeNum].blockCount-(size/BLOCK_SIZE)) - target_block;
char *raw_content = malloc(sizeof *raw_content * loop_count * BLOCK_SIZE);
assert(raw_count);
for (loop = 0; loop < loop_count; loop++) {
   i = target_block + loop;
   disk_read(inode[nodeNum].directBlock[i], raw_content + content_offset);
   content_offset += BLOCK_SIZE;
}

还建议检查disk_read()

的成功与否