10

memmove/memcpy/strcpy のプロトタイプの 2 番目の引数は似ています: たとえば:

void *memmove(void *dest, const void *src, size_t n); //const void*
char *strcpy(char *dest, const char *src); //const char*

しかしどうやら、dest と src が重なる場合、src の内容が変更され、const void/char *? に違反します。

4

4 に答える 4

20

const void*は、参照先がそのポインターによって変更されないことを意味します。

同じオブジェクトへの他の非 const ポインターがある場合 (「エイリアシング」とも呼ばれます)、もちろんそれらを介して変更することができます。あなたが説明したシナリオでは、その他のポインターはdest.

ちなみに、 のstrcpy場合、領域が重なった場合の動作は未定義で、C99 ではシグニチャはchar *strcpy(char * restrict s1, const char * restrict s2);です。しかし、memmove の場合、エイリアシングは問題ありません。重なり合う領域を与えることで、領域を変更する「許可」を与えたことdestになります。

于 2011-09-16T13:28:14.970 に答える
7

引数は、そのポインタを使用してポイントされたメモリを決して変更しないことconst void *を示すためにマークされています。オーバーラップが発生した場合、メモリはポインターではなくポインターを使用して変更されるため、保証に違反することはありません。memmovesrcdestsrc

于 2011-09-16T13:29:41.770 に答える
4

これは、 が指すメモリを直接memmove変更しないことを保証することを意味します。src

もちろん、2 つのブロックがオーバーラップmemmoveすると、いわゆる「const」メモリが変更されます。const名前に付随する契約です。実際のメモリを読み取り専用にする方法はありません。

于 2011-09-16T13:25:10.553 に答える
4

上記のように、memove は「src」ポインターを介してメモリーの内容を変更するのではなく、「dest」ポインターを介して変更します。

const はポインターの使用方法を参照し、メモリ保護を追加しません。

両方のポインタがメモリの重複領域を指している場合、コピーが「src」から開始してインクリメントするか、「src + n」から開始してデクリメントするかが定義されていないため、何かが起こる可能性があります。

于 2011-09-16T13:35:23.090 に答える