【发布时间】:2013-12-10 16:37:20
【问题描述】:
我正在编写一些非常低级的 C 代码来模拟家庭作业项目的“文件系统”。文件系统由固定大小的块(1024B)组成,但允许一个“文件”跨越多个不连续的块。
我需要能够将任何类型的void *buf 写入具有模仿write 的函数的文件。假设我们有以下签名myWrite(int blockNum, void *buf, int nbytes。
假设nbytes 大于1024,所以我必须写入多个块。所以我需要做类似的事情:
int remainder = nbytes - 1024;
myWrite(firstBlock, buf, 1024);
myWrite(nextBlock, (buf + 1024), remainder);
myWrite 调用下面的标准write 函数,传入类似的参数。
问题在于指针算术,当我在void* 上进行指针算术时,C 不喜欢。我得到一个EINVAL 或EARGS(取决于Mac 还是Linux)说C 不喜欢我传递给write 系统调用的指针,因为它是通过void 指针算法生成的。
问题是,我不知道我要写什么样的数据类型。有时是 char *,有时是自定义的东西,例如 my_type *,代表程序代码中的结构。
有没有办法解决这个问题?我需要有一个这样的概括性写作。我当前的实现大部分时间都有效,但有时会失败。
【问题讨论】:
-
假设
buf被声明为void *,并且1024是一个字节数,那么(unsigned char *) buf + 1024应该没问题。 -
这适用于任何数据类型吗?
-
如果你只是写出字节,那么底层类型是无关紧要的。
-
我在写调用中仍然收到无效参数。有趣的是,当我做类似的事情但使用 read() 时,我没有收到错误。
-
虽然形式上不正确,但
void *指针算法应该没有问题,因为 Linux 下的每个主要编译器都在执行预期和记录的操作。我猜,您的buf太小或nbytes - 1024评估为负数或太大。我建议通过strace和/或valgrind运行您的程序
标签: c pointers io filesystems system-calls