Я чувствую путаницу из-за ошибки шины в строке (C)

Я чувствую путаницу по поводу замены двух символов в одной строке на C. Это хорошо работает, когда я устанавливаю его в виде массива:

char strBase[8] = "acbdefg";

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

char *strBase = "acbdefg";

Большое спасибо за то, что кто-то может объяснить это или дать мне подсказку!

3 ответа

Разница здесь в том, что

 char *strBase = "acbdefg"; 

разместит acbdefg в только для чтения части памяти и делая strBase указатель на это, что делает любую операцию записи в эту память недопустимой.

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

При этом:

char strBase[8] = "acbdefg";

помещает буквенную строку в постоянную память и копирует строку во вновь выделенную память в стеке.

Таким образом, этот массив размещается в памяти, и как долго он живет, зависит от того, где объявление появляется. Если объявление находится внутри функции, оно будет жить до конца блока, в котором оно объявлено, и почти наверняка будет размещено в стеке; если он находится вне функции, он, вероятно, будет храниться в "инициализированном сегменте данных", который загружается из исполняемого файла в записываемую память при запуске программы.

Изготовление

strBase[0] = 'x';

законны.

Ваша проблема связана с распределением памяти. Вам нужно место для хранения ваших персонажей. Когда вы написали:

char strBase[8] = "acbdefg";

Вы создали автоматическое хранилище (часто называемое стеком) и инициализировали его строкой символов. Но когда вы написали:

char *strBase = "acbdefg";

Вы создали указатель и указали на постоянную строку. Компилятор помещает это в часть памяти, которая помечена как доступная только для чтения. Если вы попытаетесь изменить это, это приведет к нарушению доступа к памяти.

Вместо этого вы можете сделать что-то вроде:

const char* strData = "acbdefg";
int size = 1024;
char *strBase = (char*)malloc(size);
strncpy(strBase, strData, size);
ProcessString(strBase);
free(strBase);

Наиболее вероятной причиной является то, что

char strBase[8] = "abcdefg";

заставляет компилятор зарезервировать память для массива из восьми символов и инициализирует его значением "abcdefg\0". По сравнению,

char *strBase = "abcdefg";

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

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

Другие вопросы по тегам