sizeof char * массив в C / Stack Overflow

Есть много подобных запросов, но в моем случае я не понимаю, что не работает:

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

РЕДАКТИРОВАТЬ: Хорошо, это объявление:

char *samplestring = "Start.";

Я на C ++, но мне нужно использовать функции, которые принимают только символы *. Позже в коде я назначаю новые строки этой переменной, например:

samplestring = "Press 'r' for red text.";

Да, компилятор выдает мне предупреждения, но я понятия не имею, как я могу использовать разные строки, если я не могу их перезаписать …

6

Решение

4 не размер строки, потому что samplestring не строка Это char*, чей размер (на вашей платформе) 4, деленный на 1 (размер char), правильно, 4.

В C ++ вы бы использовали std::string и length() метод.

В C вы бы использовали strlen который принимает в качестве параметра NULL-завершенный указатель на символ.

13

Другие решения

Есть два способа сделать строковую константу, и ваша техника работает только на первом. Первый создает массив символов, размер которого вы можете получить во время компиляции, а другой создает указатель в массив символов.

char samplestring[] = "hello";
char * samplestring = "hello";

Попытка принять размер второго случая так, как вы это делаете, просто дает вам размер указателя. В 32-разрядной сборке размер указателя составляет 4 символа, то есть указатель занимает столько же памяти, сколько 4 символа.

Следующее будет всегда дать правильную длину для правильно завершенной нулем строки, но она медленнее.

mysize = strlen(samplestring);
4

Прежде всего, sizeof(samplestring[0]) такой же как sizeof(*samplestring)они оба возвращают размер первого элемента samplestring массив. И, предполагая, samplestring это массив символов, sizeof(char) определяется как 1.

Вы не показали, как samplestring объявлен Это может быть одно из следующих:

char const *samplestring = "Hello, World!";

или же

char *samplestring = malloc( ... );

или же

char samplestring[10];

В первых 2 случаях тип samplestring является char *, так sizeof(samplestring) возвращается sizeof(char *), который на вашей платформе 4.

В третьем случае тип samplestring является 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 если у вас есть завершенная строка NULL).

4

Похоже, у вас есть указатель, а не массив. Массивы преобразуются в указатели, когда программа требует этого, поэтому вы получите:

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 чтобы найти длину строки с нулевым символом в конце, но в большинстве случаев вам придется самостоятельно следить за размерами массива.

1

Вы спрашиваете размер указателя на символ. Я полагаю, вы используете 32-битную систему.

Если вы используете C ++, используйте std :: string:

std::string samplestring("Hello world");
std::cout << samplestring.size() << std::endl;
0

Sizeof элемента возвращает размер памяти, выделенной для этого объекта.
В вашем примере строка, вероятно, где-то объявлена ​​как

samplestring[4]

В этом случае размер памяти равен 4.
Метод, который вы, вероятно, хотите использовать в своем приложении:

strlen(samplestring);

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

0
По вопросам рекламы [email protected]