我一直在编写虚拟机,并且我注意到发生了一些奇怪的事情,尽管我很久以前就编写了这个函数。无论如何,我的虚拟机读取这样的文件:
0002 000A 0001 0004 0000
但是,当我在 0000 或新行之后没有有任何空格时...它会崩溃。另一个非常奇怪的事情,让我相信这不是文件加载,是当您从文件中删除 0000
和空格时......它起作用了吗? !我尝试过通过 GDB 运行它,但它确实有效——显然这被称为 heisenbug 或其他东西。我认为这是由于文件加载方式造成的,您可以在 this function here on github 中看到。 ,或者只是阅读下面的片段。
void load_program(vm *self) {
FILE *file = fopen("testing.ayy", "r");
if (file != NULL) {
if (fseek(file, 0, SEEK_END) == 0) {
long file_size = ftell(file);
if (file_size == -1) {
perror("could not read filesize\n");
exit(1);
}
self->source = malloc(sizeof(char) * file_size);
if (fseek(file, 0, SEEK_SET) != 0) {
perror("could not reset file index\n");
exit(1);
}
size_t file_length = fread(self->source, sizeof(char), file_size, file);
if (file_length == 0) {
perror("given file is empty\n");
exit(1);
}
self->source[file_size] = '\0';
}
fclose(file);
}
else {
perror("could not read file: \n");
exit(1);
}
self->source_compact = strdup(self->source);
self->source_compact = deblank(self->source_compact);
// here we divide because strlen is in characters,
// whereas each instruction code should be 4 characters
// so we're converting char size to num of instructions
self->instructions_size = strlen(self->source_compact) / INSTRUCTION_LENGTH;
int i;
for (i = 0; i < self->instructions_size; i++) {
char *instr = substring(self->source_compact, i);
if (strcmp(instr, ERROR_CODE)) { // not equal to NOPE
if (self->instructions != NULL) {
self->instructions = add_instructions(self->instructions, strtol(instr, NULL, 16));
}
else {
self->instructions = create_instructions(strtol(instr, NULL, 16));
}
}
}
self->instructions = reverse(self->instructions);
}
但是我添加了一个 GitHub 链接,因为我不确定它是否是那个函数;或者如果它是由于整个源代码中发生的任何事情造成的——所以如果任何 C 专家可以帮助我,那就太棒了:)。我确定它位于 vm.c
或 vm.h
中,对于糟糕的代码深表歉意;我在学习时从未真正深入研究过文件 IO(这是一个大错误)。
最佳答案
self->source = malloc(sizeof(char) * file_size); ... self->source[file_size] = '\0';
您需要为终止零再分配一个字节。索引 source[file_size]
实际上是超出已分配内存末尾的一个字节。写入该位置可能会破坏其他一些变量或 malloc()
使用的内部结构。做到:
self->source = malloc(sizeof(char) * (file_size + 1));
或者只是:
self->source = malloc(file_size + 1);
sizeof(char)
始终为 1
,因此它是多余的。
如果你想在 self->source
的类型发生变化时保护自己,可以使用:
self->source = malloc ((file_size+1) * sizeof *self->source);
它会自动分配正确的大小。
在尝试访问内存之前,您还应该检查分配是否成功。
关于c - C 文件 IO 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26822799/