memcpy:警告:解除引用'void*'指针

Ton*_*yGW 4 c file memcpy

我使用read()函数从文件中读取40个字符,并且需要从10的偏移量复制20个长度.换句话说,我需要将第10个到第30个字符的memcpy复制到新的内存中地址.但是,当我运行我的代码(见下文)时,我收到了警告消息:warning: dereferencing ‘void *’ pointer

int main()
{
    void *buffer = malloc(40);
    int fd = open("example20.txt", O_RDONLY);
    printf("the value of fd is %d \n", fd);


/* read 40 characters from the file */ 
int bytes_read = read(fd, buffer, 40);

void *new_container = malloc(20);

/* copy from buffer, starting offset at 10 for length of 20 */
memcpy(new_container, &buffer[10], 20);
printf("new_container is %s \n", (char *) new_container);

return 0;
}
Run Code Online (Sandbox Code Playgroud)

我想知道这个错误意味着什么,以及如何解决它?

edit1:我找到了解决问题的方法:将缓冲区从void*转换为新的char*指针.

char *buffer2 = (char *) buffer;
memcpy(new_container, &buffer2[10], 20);
Run Code Online (Sandbox Code Playgroud)

EDIT2:我发现使用无效的方式*指针的memcpy:memcpy(new_container, buffer+10, 20); 以这种方式变量"buffer"可以是void*类型

Who*_*aig 6

警告是由于这个:

&buffer[10]
Run Code Online (Sandbox Code Playgroud)

void没有大小,[]操作员需要具体的数据类型才能以定义的方式运行.这是一个警告可能是由于您的编译器void*以某种unsigned char *方式支持(例如,gcc具有此扩展).但它不标准.因此警告.

改变这个:

void *buffer = malloc(40);
Run Code Online (Sandbox Code Playgroud)

对此:

unsigned char *buffer = malloc(40);
Run Code Online (Sandbox Code Playgroud)


aja*_*jay 6

改变线

memcpy(new_container, &buffer[10], 20);
Run Code Online (Sandbox Code Playgroud)

memcpy(new_container, (char *)buffer + 10, 20);
Run Code Online (Sandbox Code Playgroud)

那是因为&buffer[10]求值&(*(buffer + 10))因为数组下标运算符的优先级高于address of运算符&.但是,由于没有大小信息,因此无法对指针buffer进行类型void *和指针运算void.使用类型转换操作者(char *)buffer提供了必要的尺寸信息,以便
(char *)buffer + 10等同于buffer + 10 * sizeof(char)或地址11在缓冲器th元素由变量指向buffer.