Представьте, что вам попался код следующего вида:
typedef unsigned char Str255[257];
Str255 Blah;
void f( Str255 s )
{
memcpy(&Blah, &s, sizeof(Str255)); // error here
}
int main()
{
Str255 x("Blah");
f( x );
}
Вопрос в том, почему данный код будет работать неверно, т.е. в Blah будет скопировано не содержимое
x, а непонятный мусор? Ошибка тут в том, что в
memcpy не нужно использовать
&, а писать
memcpy(Blah, s, sizeof(Str255));. Потому что
s и
&s — это разные указатели, и они даже имеют разный тип:
unsigned char * and
unsigned char (*)[257] соответсвенно. Обычно указатель на первый элемент массива и указатель на массив — это одно и тоже, но в нашем случае это не так. Посмотри как выглядит функция
f, если не использовать
typedef:
void f( unsigned char* s )
{
memcpy(&Blah, &s, sizeof(Str255)); // error here
}
При вызове этой функции, в соответсвии с пунктом 4.2 стандарта C++, массив будет неявно преобразован в указатель и мы получим, что
s указывает на массив с текстом, но
&s будет указывать на указатель, который хранится на стеке, т.е. при копировании мы получим содержимое стека в
Blah. Чтобы избежать такого недоразумения лучше использовать
std::string в C++, ну а в C просто не использовать
typedef для строк и понимать что происходит.