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);

который возвращает размер нулевой завершенной строки (без завершения)