2012-06-15 2 views
1

Можно создать дубликат:
Sizeof an array in the C programming language?Как я могу знать legth массива в C++

У меня есть массив полукокса, и я хочу, чтобы обработать его в функции, я попытался код как это:

int main(){ 
    char *word = new char [5];  
    /*here we make this word 
    .... 
    */ 

    process(word); 
    puts(word); 
} 

void process(char *word){ 
    int sizeOfWord = sizeof(word)-1; 
    /* here is cycle that process the word, I need it lenght to know how long cycle must be 
    ..... 
    */ 
} 

Но я не могу получить длину массива с sizeof. Зачем? И как я могу это получить?

+0

[Здесь] (http://stackoverflow.com/questions/492384/how-to-find-the-sizeofa-pointer-pointing-to-an-array) отвечает на один и тот же вопрос, хотя для C. – benjer3

ответ

3

Вы не можете. С указателем нет способа узнать размер.

Что вы должны сделать, передайте длину word на ваш process.


Вы должны знать, что существует разница между массивами и указателями. Массивы действительно представляют собой ряд элементов, поэтому sizeof массива дает его размер (в байтах). Указатель с другой стороны - это просто адрес. Он может даже не указывать на массив. Поскольку оператор sizeof вычисляется во время компиляции (за исключением массивов переменной длины), он не может знать, что вы имеете в виду.

Think этого примера:

void process(char *word); 

int main(){ 
    char *word = new char [5]; 
    char *word2 = new char [10]; 

    process(word); 
    process(word2); 
    /* ... */ 
} 

void process(char *word){ 
    int sizeOfWord = sizeof(word)-1; // what should this be? 
    /* ... */ 
} 

Теперь, зная, что sizeof в этом случае вычисляется во время компиляции, какое значение вы думаете, он должен получить? 5? 10?


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

0

Нет, это не сработает. sizeof указатель возвращает только размер типа указателя, а не тип массива. Когда вы передаете массив как параметр функции, массив распадается на на указатель, что означает, что компилятор больше не будет знать, на что именно указывает, и если это массив, как долго это может быть. Единственные способы для вас, чтобы знать его внутри функция

  • передать длину в качестве дополнительного параметра, или
  • добавить дополнительный элемент терминатора в массив.

Обратите внимание, что массивы на C и C++ не сохраняют их размер каким-либо образом, поэтому программист должен помнить об этом и программировать соответствующим образом. В приведенном выше коде вы знаете, что фактический размер a равен 5, но компилятор (и среда выполнения) не знает об этом. Если вы объявили его в виде массива, т.е.

char[] word = new char [5]; 

компилятор следить за его размера и sizeof бы вернуть этот размер (в байтах), в то время как в рамках этой декларации. Это позволяет применять хорошо известную идиому, чтобы получить фактический размер массива:

int size = sizeof(a)/sizeof(char); 

Но опять же, это работает только до тех пор, как компилятор знает, что a на самом деле массив, так что это не возможно, внутри где a передается как параметр (указатель).

+0

и как узнать размер массива? – mishkapp

+0

@mishkapp, читая код :-) Смотрите мое обновление для деталей. –

2

U следует использовать вместо strlen().

EDIT: Если предположить, что word является действительным словом с \0 в конце.

В любом случае, вы используете c++, поэтому вы должны использовать какой-то контейнер, например std::string.

+0

'strlen' не будет передавать истинный размер его массива символов, если' \ 0' имеет индекс меньше размера. –

+0

уверен, но ОП назвал его переменным «слово», поэтому я предполагаю, что будет действительное слово без белых символов. – IProblemFactory

+2

@ProblemFactory: но если слово «the», то длина слова (даже включая nul terminator) меньше размера массива, в котором записано это слово. Так что вся длина слова будет использована зависит от того, почему вопросник хочет знать размер массива. –

0

Поскольку массивы «распадаются» в указатели на их первые элементы в коде вроде этого, вы не можете. Указатель не «знает», как большой блок памяти, на который он указывает. Вам нужно передать размер отдельно, например.

void process(char *word, size_t length); 
0

Существует только один способ узнать длину массива в C/C++: уже зная об этом. Вам нужно будет передать длину массива в качестве другого параметра.

Если вы говорите конкретно о строках, найдите нулевой символ в массиве, а затем используйте его индекс + 1 как длину (что в основном выполняет функция strlen()).

В противном случае, возможно, вы могли бы просто использовать std :: string вместо этого, а затем получить его свойство length?

0

Вам необходимо передать длину массива функции process или использовать символ null (\0), чтобы отметить конец.

Предполагая, что последний можно использовать

void process(char *word) 
{ 
    while (*word) 
    { 
    //do stuff with the character *word 
    ++word; 
    } 
} 
2

Если ваш массив всегда char* или const char* и содержит нулевые законченные строки, вы можете использовать strlen, или даже более легко использовать std::string класс и его соответствующие методы.

Если это не нуль строки (например, его простой массив байт, или ваш вопрос о массивах в целом и char просто пример), используйте std::vector<char> или std::array<char, 5> и вызвать их .size() методы.

0

В ОС Windows есть функция _msize для получения выделенного объема памяти в куче в байтах. В VS2005 и VS2008 он отлично работал с оператором new, потому что он использовал malloc для выделения памяти. Должен отметить:

Это не стандартный способ, поэтому вы НЕ должны его использовать!

Object * addr = new Object[xxx]; 
size_t number_of_objects = _msize(addr)/sizeof(Object); 
0

Другие ответы объяснили подробно, почему вы не можете получить размер классического C-массива, но я хочу отметить следующее.

Ваш пример не хватает

delete [] word; 

в конце основной.В противном случае у вас есть утечка памяти.

Это показывает, почему предпочтительный способ работы с массивами в C++ использует std::vector или - в случае фиксированной длины - новый std::array и в случае символьных строк std::string. Компилятор будет управлять базовым хранилищем для вас. Все эти классы предоставляют функцию size.

Смежные вопросы