const void *
和void *
有什么区别?在什么情况下可以将void指针转换为const void
指针?
const void *
指向的内存不应该被修改。
void *
(非const)指向的内存可以被修改(但不能直接使用void *
修改,需先转换类型)。
当你使用memmove()
时,源地址被强制转换为const void *
:
void *memmove(void *dst, const void *src, size_t nbytes);
当你知道你不会修改指针所指向的内存时,就可以在任何时候将void指针转换为常量void指针。这适用于任何指针类型,而不仅仅是void指针。
相反地,将常量指针转换为非常量指针是一种更加危险的操作。不能保证指向的内存实际上是可修改的;例如,字符串字面值可以存储在只读(常量)内存中,如果你使用强制类型转换丢失const限定并尝试修改该字符串,很可能会导致分段错误或类似的错误-程序将突然停止而不受您的控制。这不是一个好事情。因此,在非常确信可以欺骗编译器的情况下,不要将指针从常量转换为非常量。请注意,编译器不喜欢被欺骗,并且通常会在最不方便的时刻报复你(例如在向重要潜在客户演示程序时,你的老板、老板的老板和老板的老板的老板都在场)。
将 void *
强制转换为 const void *
是完全合理的,编译器应该在幕后自动执行此操作,而无需您考虑任何事情,但反过来则是危险的,必须避免。
记住,如果函数接受一个 const
指针,则可以自由地向其传递 const
或非 const
值。说你使用了 const
指针只是声明该内存不会被您的函数修改。
例如:(注意标有 DANGER 的行应该会引发编译器错误)
const void *p_const;
void *p_buffer;
// const pointers are allowed to hold static memory
p_const = "Foo"; // allowed
p_buffer = "Foo"; // DANGER!!!
// casting to const is implicit
p_const = malloc(LEN); // allowed - implicit cast
p_buffer = malloc(LEN); // allowed
// casting to const implicit again
write(STDOUT, p_const, LEN); // allowed
write(STDOUT, p_buffer, LEN); // also allowed - implicit cast
// const memory cannot be used where mutable memory is expected
read(0, p_buffer, LEN); // allowed
read(0, p_const, LEN); // DANGER!!
// To make the above more obivous, we'll skip the intermediate variable
// and place instead what it holds
read(0, malloc(LEN), LEN); // allowed - useless but at least no crashes
read(0, "foo", 4); // DANGER!!!
void do_something(const void* ptr, int length);
// Since the signature is a const pointer, I know I can call it like this:
do_something("foo",4);
void do_something(void* ptr, int length);
// This tells me that the function may overwrite my value.
// The safe solution therefore looks more like this:
char *myptr = char[4];
memcpy(myptr,"foo",4);
do_something(myptr,4);
const
指针转换为非const
指针的情况,你应该将指向的值复制到可变部分内存中,并将副本传递给函数,而不是原始值。如果这听起来让人头疼,那是因为它确实很麻烦。如果你发现自己处于这种情况下,那么你可能做错了什么。const
指针。如果它保存的是一个“缓冲区”,那么它就是一个非const
指针。const
,除非你打算写入该内存。遵循这个规则将帮助你避免程序逻辑中的灾难性问题。
const void * a
表示这个特定的指针不能修改数据,但是可以修改指向数据的指针。另一方面,void * const a
表示指针不可变,但是数据可以被修改。void *
表示可变指针可以指向可被修改的数据。 - paraflou