2017-01-26 11 views
4

Я не нашел ничего в стандарте C11, заявив, что строка не может быть длиннее SIZE_MAX (где SIZE_MAX обозначает максимальное значение типа size_t). Например. если size_max - long, а в моей реализации есть тип long long, который строго больше long, тогда я мог бы определить и индексировать такую ​​строку, используя long long.Может ли строка, соответствующая стандарту, длиннее символов SIZE_MAX?

Однако, это будет означать, некоторые необычные ситуации: strlen, например, может быть не в состоянии вернуть фактический размер строки, так как результат будет преобразован в size_t в конце концов, таким образом, строка длины SIZE_MAX+1 будет например, имеет размер 0. Это, например, нарушит стандарт и, таким образом, предотвратит существование таких строк? Для справки, 7.24.6.3 говорит только, что:

7.24.6.3 Функция StrLen

Синопсис

#include <string.h>

size_t strlen(const char *s);

Описание

Функция strlen вычисляет длину строки, на которую указывает s.

Возвращает

Функция StrLen возвращает количество символов, которые предшествуют завершающий нулевой символ.

Я что-то пропустил, или это было бы совершенно справедливо (данная стандартная реализация) C11?

+0

"*, то я мог бы выделить [...] строка, используя длинный длинный. *", Предполагая, динамическое выделение, вы не можете, как 'таНос()' 'принимает size_t'. – alk

+1

Проект C11 «рекомендует» в разделе 7.19/4: «* Типы, используемые для' size_t' и 'ptrdiff_t', не должны иметь целочисленный ранг преобразования больше, чем у' signed long int', если реализация не поддерживает объекты достаточно большой чтобы сделать это необходимым. * "Это косвенно говорит, что не было бы объекта больше, чем' SIZE_MAX'. – alk

+0

@alk хорошо отмеченный, я имел в виду «объявить» вместо «выделить». Я исправил эту фразу. – anol

ответ

3

Из [6.5.3.4 SIZEOF и alignof операторов]:

4 Когда SizeOf применяются к операнду, который имеет типа символ, символ без знака, или, подписанного символа (или квалифицированной его версии), результат равен 1. При применении к операнду, имеющему тип массива, результатом является общее количество байтов в массиве. 102) При применении к операнду, который имеет структуру или тип объединения, результатом является общее количество байтов в таком объекте, включая внутреннее и конечное заполнение.

5 Значение результата обоих операторов определено реализацией, а его тип (целочисленный тип без знака) - size_t, определенный в "stddef.h" (и других заголовках).

Отсюда следует, что размер любого массива не может быть больше, чем size_t может быть выполнено, и, следовательно, размер строки не может быть больше, чем SIZE_MAX.

Редактировать: с использованием calloc см. [7.22.3.2 Функция calloc]:

Функция calloc выделяет пространство для массива объектов nmemb, каждый из которых имеет размер. Пробел инициализируется ко всем битам нуль.

Он выделяет пространство для массива, но размер массива должен вписываться в size_t, так что вы не можете выделить более SIZE_MAX с calloc. Он должен вернуть NULL, если вы попробуете это сделать.

+0

Thar не следует. Вы можете передать два аргумента calloc(), которые создают объект, больший, чем SIZE_MAX, и записывают строку в это. Стандарт не ясно, что должно произойти - в идеале calloc() wil возвращает null. –

+0

@MalcolmMcLean Нет, вы не можете выделить более 'SIZE_MAX' с' calloc'. См. Править. –

+0

@MalcolmMcLean некоторые утверждают, что это неопределенное поведение для передачи таких аргументов. Стандарт не ясен. –

0

Приведем некоторые спецификации вместе.


строка представляет собой непрерывную последовательность символов и заканчивающихся в том числе первого нулевого символа. C11 §7.1.1 1 (курсив мой)


Когда sizeof применяется ... операнд, который имеет тип массива, в результате общее число байтов в массиве ..... C11 §6.5.3.4 4

size_t , который является целым числом без знака результата оператора sizeof; C11 §7.19 2

Предел size_t является SIZE_MAX C11 7.20.3 2


Если мы используем только массив символов объектов или выделенной памяти для массива из символов, самая длинная строка размер SIZE_MAX. Максимальное возвращаемое значение для strlen(x_big) - SIZE_MAX - 1.


Если код успешно со следующим, то код отважился далеко и в этом случае, строка может быть построено больше, чем SIZE_MAX, но я подозреваю, что либо calloc() вернется NULL первой или (char *) ptr потерпит неудачу.

double *ptr = calloc(SIZE_MAX, sizeof *ptr); 
assert(ptr); 
char *s_waybig = (char *) ptr; 

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

  • Нет связанных вопросов^_^