sizeof char * массив в C / C++
есть много аналогичных запросов, но в моем случае я не понимаю, что не работает:
int mysize = 0;
mysize = sizeof(samplestring) / sizeof(*samplestring);
std::cout << mysize << 'n' << samplestring;
вот результаты:
4
Press 'q' to quit.
как это возможно? 4 определенно не размер этой строки. Я даже попробовал следующее, с тем же результатом:
mysize = sizeof(samplestring) / sizeof(samplestring[0]);
EDIT: Ok, это объявление:
char *samplestring = "Start.";
Я на C++, но мне нужно использовать функции, которые принимают только char *. Позже в коде я назначаю новые строки эта переменная, например:
samplestring = "Press 'r' for red text.";
да, компилятор дает мне предупреждение, но я понятия не имею, как я могу использовать разные строки, если я не могу их переписать...
6 ответов
4
не размер строки, потому что samplestring
Не строку. Это char*
, размер которого (на вашей платформе) 4, деленный на 1 (размер char
), правильно, 4.
в C++, вы должны использовать std::string
и length()
метод.
в C, вы должны использовать strlen
который принимает в качестве параметра указатель char с нулевым концом.
есть два способа сделать строку постоянной, и ваша техника работает только на первом. Первый создает массив символов, размер которых вы можете получить во время компиляции, а другой создает указатель к массиву символов.
char samplestring[] = "hello";
char * samplestring = "hello";
попытка взять размер второго случая так, как вы это делаете, просто дает вам размер указателя. На 32-битной сборке размер указателя составляет 4 символа, т. е. указатель принимает одинаковое количество памяти 4 символов.
следующее всегда дайте правильную длину для правильно завершенной нулевой строки, но она медленнее.
mysize = strlen(samplestring);
прежде всего, sizeof(samplestring[0])
это то же самое, что sizeof(*samplestring)
, они оба возвращают размер первого элемента samplestring
массив. И, если samplestring
представляет собой массив символов,sizeof(char)
определяется как 1.
вы не показали, как samplestring
объявлена. Это может быть одно из следующих:
char const *samplestring = "Hello, World!";
или
char *samplestring = malloc( ... );
или
char samplestring[10];
в первых 2 случаях типа samplestring
is char *
, так что sizeof(samplestring)
возвращает sizeof(char *)
, который, по ваша платформа 4.
в третьем случае, типа samplestring
is char[10]
(массив из 10 символов), но если вы вызываете функцию, которая принимает char *
в качестве параметра char массив будет распад на указатель, указывающий на первый элемент массива. В этом случае, пытаясь напечатать sizeof
внутри функции все равно приведет к размеру печатаемого указателя.
если вы хотите, чтобы размер исходного массива будут напечатаны в функция, тогда параметр функции должен быть указателем на исходный тип массива (и тип включает размер исходного массива).
#include <stdio.h>
void foo( char (*arr)[42] )
{
printf( "%u", (unsigned)sizeof(*arr) );
}
int main()
{
char arr[42];
foo( &arr );
return 0;
}
выход:
42
это фиксирует размер массива, который может быть передан функции и не желательно во многих случаях. Единственное другое решение-отслеживать массив самостоятельно (или использовать strlen
если у вас есть строка с нулевым завершением).
похоже, что у вас есть указатель, а не массив. Массивы преобразуются в указатели, когда этого требует программа, поэтому вы получите:
size_t size(char * p) { // p is a pointer
return sizeof(p) / sizeof(*p); // size of pointer
}
size_t size(char p[]) { // p is also a pointer
return sizeof(p) / sizeof(*p); // size of pointer
}
хотя, с sizeof (char) == 1
, деление здесь избыточно; если бы указатель был на больший тип, то вы получили бы другой неожиданный результат.
в C++ (но, очевидно, не C) вы можете вывести размер массива в качестве параметра шаблона:
template <typename T, size_t N>
size_t size(T (&)[N]) {
return N; // size of array
}
или вы можете использовать классы, такие как std::vector
и std::string
отслеживать размер.
в C, вы можете использовать strlen
чтобы найти длину строки с нулевым концом, но в большинстве случаев вам нужно будет самостоятельно отслеживать размеры массива.
вы спрашиваете размер указателя на char. Итак, я думаю, вы используете 32-битную систему.
Если вы используете C++, используйте std:: string:
std::string samplestring("Hello world");
std::cout << samplestring.size() << std::endl;
sizeof элемента возвращает размер памяти, выделенной для этого объекта. В вашем примере строка, вероятно, объявлена где-то как
samplestring[4]
в этом случае размер памяти 4. Метод, который вы, вероятно, хотите в своем приложении, -
strlen(samplestring);
который возвращает размер нулевой завершенной строки (без завершения)