Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Инициализация массивов типа char

Автор вопроса: matcheekОтветов: 8

Я хочу инициализировать произвольные большие строки. Это строка символов с нулевым завершением, но я не могу распечатать ее содержимое. Кто-нибудь может сказать мне, почему?

char* b;
char c;
b = &c;
*b = 'm';
*(b+1) = 'o';
*(b+2) = 'j';
*(b+3) = 'a';
*(b+4) = '\0';
printf("%s\n", *b);
  • *(b+1) - это память, которой вы не владеете и которой не должны пользоваться. yehnan 01.06.2011

carrayspointerschar

Ответы

Ответ 1 · рейтинг 11 · Oliver Charlesworth

Ваше решение вызывает неопределенное поведение, поскольку *(b+1) и т. д. находятся за пределами переменной стека c. Поэтому, когда вы пишете им, вы записываете всю память, которая вам не принадлежит, что может привести к разного рода повреждениям. Кроме того, вам нужно printf("%s\n", b) (printf ожидает указатель на %s).

Решение зависит от того, что вы хотите сделать. Вы можете инициализировать указатель на строковый литерал:

const char *str1 = "moja";

Вы можете инициализировать массив символов:

char str2[] = "moja";

Это также можно записать как:

char str2[] = { 'm', 'o', 'j', 'a', '\0' };

Или вы можете вручную присвоить значения вашей строки:

char *str3 = malloc(5);
str3[0] = 'm';
str3[1] = 'o';
str3[2] = 'j';
str3[3] = 'a';
str3[4] = '\0';

...

free(str3);

Ответ 2 · рейтинг 2 · Pavan Manjunath

Это может привести к ошибке сегментации! *(b+1), *(b+2) и т. д. относятся к незанятым областям. Сначала выделяй память, а потом пиши в нее!

Ответ 3 · рейтинг 1 · N.R.S.Sowrabh

b не хватает места для хранения всех этих символов. Выделите достаточно места, используя malloc, или объявите b массивом char.

Ответ 4 · рейтинг 1 · king_nak

Ваш код вообще небезопасен! Вы выделяете в стеке только 1 символ с помощью char c;, но записываете в него 5 символов! это приведет к переполнению стека, что может быть очень опасно.

Еще одно: вы не должны разыменовывать строку при ее печати: printf("%s\n", b);

Почему бы просто не написать const char *b = "mojo";?

Ответ 5 · рейтинг 1 · Diego Sevilla

Вам нужно выделить для него место в памяти либо с помощью malloc, либо с помощью статического массива. Здесь, в вашем коде, вы используете адрес только одного символа для хранения адресов этих символов, и других, следующих за ним. Это не определено.

Отметьте, шаг за шагом, что вы делаете. Во-первых, вы назначаете указатель на одно символьное пространство в памяти. Затем, используя *b = 'm', вы устанавливаете в этой памяти символ 'm'. Но затем вы получаете доступ к следующей позиции памяти (которая не определена, поскольку для этой позиции не зарезервирована память) для сохранения другого значения. Это не сработает.

Как это сделать?

У вас есть два варианта. Например:

char *b;
char c[5];
b = &c[0];
*b = 'm';
... //rest of your code

Это будет работать, потому что у вас есть место для 5 символов в c. Другой вариант - напрямую выделить память для b с помощью malloc:

char * b = (char*) malloc(5);
*b = 'm';
... // rest of your code

Наконец, возможно, это не то, что вы хотите, но вы можете либо инициализировать массив символов, либо указатель, используя строковый литерал:

char c[] = "hello";
const char* b = "abcdef";

Ответ 6 · рейтинг 1 · garph0

printf не печатает, потому что ожидает char*, поэтому вы должны передавать b, а не *b. Чтобы инициализировать указатель на строковую константу, вы можете сделать что-то вроде:

char *s1 = "A string"

or

char s2[] = "Another string"

или выделить буфер с помощью char *b = malloc(5), а затем записать в этот буфер (как вы это сделали, или с помощью строковых функций)

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

Ответ 7 · рейтинг 1 · Ozair Kafray

Если вы напишите следующее вместо вашего printf, он напечатает первый символ.

printf("%c\n", *b);

Чтобы у вас были произвольно большие строки, вам нужно будет использовать такую ​​библиотеку, как bstring или напишите свой собственный.

Это потому, что в C нужно получить память, использовать ее и соответственно освободить. b в вашем случае указывает только на символ, если вы не выделяете ему память с помощью malloc. А для malloc нужно указать фиксированный размер.

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

Ответ 8 · рейтинг 1 · Gangnus

printf("%s\n", *b);

Почему *?

printf("%s\n", b);

это то, что ты хочешь

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы