C ++ strcpy неконстантное выражение в виде массива - PullRequest
2 голосов
/ 24 января 2010

Я вернулся к C ++ после долгого времени в C #, PHP и других вещах, и нашел что-то странное:

temp.name = new char[strlen(name) + strlen(r.name) + 1];

это компилируется

temp.name = (char *)malloc(sizeof(char[strlen(name) 
     + strlen(r.name) + 1]));

это не так (temp.name является символом *)

Ошибка компилятора

ошибка C2540: непостоянное выражение в виде массива

Кто-нибудь знает, в чем может быть проблема и как ее можно исправить? Спасибо.

Ответы [ 3 ]

6 голосов
/ 24 января 2010

sizeof(...) ожидает постоянного выражения времени компиляции. strlen - это не выражение времени компиляции, это функция, которую нужно выполнить, чтобы получить результат. Следовательно, компилятор не может зарезервировать достаточное хранилище для массива, объявленного так:

char c[strlen("Hello")];

Хотя длина строки явно равна 5, компилятор не знает.

Чтобы избежать этой ловушки, не используйте sizeof здесь. Вместо этого:

char* c = (char*)malloc(strlen(name)+strlen(rname)+1);

Это дает вам указатель на n байтов в ответ. sizeof(char)==1 всегда верно, поэтому число байтов в буфере равно количеству символов, которые вы можете сохранить в нем. Для malloc массивов другого типа, умножьте на статический размер одного элемента массива:

int* c = (int*) malloc(sizeof(int)*100);

Это нормально, потому что sizeof применяется к выражению времени компиляции. Конечно, путь C ++ намного чище:

int* c = new int[100];
1 голос
/ 24 января 2010

Проблема в char[...], который является типом массива, а в C ++ (и C89) размеры массивов должны быть константами времени компиляции. Вы, вероятно, должны использовать std :: string вместо того, чтобы выделять память вручную new[] или malloc(), но если вы предпочитаете использовать ручное выделение, рассчитайте размер непосредственно как количество символов вместо использования массивов и sizeof сделай это.

0 голосов
/ 24 января 2010

malloc требует size_t в качестве входных данных, то есть вам нужно вычислить фактический размер и передать его вместо указания типа:

temp.name = (char *) malloc( (strlen(name) + strlen(r.name) + 1)) * sizeof(char));

Возможно, вы все равно должны использовать new, поэтому я не вижу никаких реальных проблем.

...