Я чувствую путаницу из-за ошибки шины в строке (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" является константной строкой, и в результате компилятор сохраняет ее в разделе памяти, который помечается только для чтения. Попытка изменить доступную только для чтения память вызывает сбой ЦП.
Ваш компилятор должен предупреждать вас о несоответствии констант во втором случае. В качестве альтернативы, ваш компилятор может иметь параметр, который изменяет доступность только для чтения константных строк.