Изменение констант струны до? [дубликат]

установить

npm install --save babel-plugin-transform-object-rest-spread
npm install --save babel-preset-env

.babelrc

{
    "presets":[
      "env","es2015", "react"
    ],

  "plugins": [
    "react-hot-loader/babel", "transform-object-rest-spread"
  ]
}

package.json

[112 ]
12
задан Community 23 May 2017 в 10:31
поделиться

5 ответов

Простое решение состоит в том, чтобы изменить объявление str кому:

char str[] = "abc";

Это делает str массив символа, который инициализируется к строке "abc". В настоящее время Вы имеете str как указатель на символ, инициализированный для указания на строку, описанную строковым литералом. Существует основное отличие: строковые литералы только для чтения для предоставления гибкости максимума компилятора на том, где сохранить их; это - UB для изменения их. Но массивы символа изменяемы, и таким образом, он должен хорошо изменить их.

PS. main() возвраты int.

13
ответ дан 2 December 2019 в 03:29
поделиться

Так как Вы учитесь для экзамена, я изложу в деталях свои комментарии немного для объяснения, что на самом деле происходит:

char *str = "abc";

str указатель, сохраненный на стеке. Это инициализируется для указания на литеральную строку "abc". Та литеральная строка будет сохраненной в разделе данных Вашего скомпилированного исполняемого файла и загружается в память, когда Ваша программа загружается. Тот раздел памяти только для чтения, поэтому когда Вы пытаетесь изменить данные, на которые указывает ул., Вы получаете нарушение прав доступа.

char* str = malloc(sizeof(char) * 4);
strcpy(str, "abc");

Здесь, ул. является тем же указателем вершины стека как первый пример. На этот раз это инициализируется, чтобы указать на блок с 4 символами памяти на "куче", что можно и читать и записать. Сначала тот блок памяти является неинициализированным и может содержать что-либо. strcpy читает блок постоянной памяти, где "abc" хранится и копирует его в блок памяти чтения-записи, та ул. указывает на. Отметьте ту установку str[3] = '\0' избыточно, так как strcpy уже делает это.

Как в стороне, если Вы работаете в Visual Studio, strcpy_s использования вместо этого, чтобы удостовериться, что Вы не перезаписываете свой буфер, если скопированная строка длиннее, чем Вы ожидали.

char str[] = "abc"; 

Здесь str теперь массив, выделенный на стеке. Компилятор будет, измерил его, точно соответствуют, строковый литерал раньше инициализировал его (включая ПУСТОЙ разделитель). Стековая память является чтением-записью, таким образом, можно изменить значения в массиве однако, Вы хотите.

char str[4] = "abc";

Это - эффективно то же как предыдущая версия, только Вы говорите компилятору, что знаете лучше, чем это делает, какой длины массив должен быть. Можно попасть в беду, если Вы меняете струну а не размер массива.

19
ответ дан 2 December 2019 в 03:29
поделиться

Поскольку это - домашняя работа, я дам совет, но я не отправлю полное решение.

Я предполагаю, что Вы получаете нарушение прав доступа на ул. [0] = 'b'? Это вызвано тем, что "abc" является строковым литералом.

Скопируйте строковые точки ул. в перед называнием реверса или станьте обратными, чтобы выделить буфер и поместить обратную строку в это.

Следует иметь в виду, что необходимо будет освободить всю память, которую Вы выделяете.

5
ответ дан 2 December 2019 в 03:29
поделиться

Lordy, Lordy. Ко всему те, которые предлагают способы на самом деле выполнить обмен, считайте вопрос тщательно; нет ничего худшего, чем необходимость повторить уже совершенно членораздельный вопрос. Независимо от метода, используемого для реализации обмена (временная подкачка, xor3-подкачка, и т.д.), этот человек, кажется, слишком знаком с фундаментальным и довольно элементарным intrinsics функции.

Однако, как уже объяснено, компилятор/компоновщик в общем помещает все строковые литералы в 'сегменте данных константы' целевого исполняемого файла, который впоследствии связан с незаписываемым дескриптором MMU во время соответствующего вызова 'загрузки/должностного лица'. Все циклы записи ЦП, впоследствии выпущенные через этот дескриптор, автоматически захватываются механизмом исключения MMU, приводящим к обязательному 'segfault' или определенному для платформы эквиваленту. Это само собой разумеется, конечно, более старые non-MMU платформы не показали бы такого поведения.

Хотя это эффективно обеспечивает поддержку во время выполнения 'постоянной/литеральной' идиомы исходного языка, несколько платформ исторически упростили явные переопределения сегмента времени компиляции. Однако этот уровень поддержки медленно уменьшался в пользу более твердого/устойчивого уровня абстракции, таким образом представляя много очевидных и часто полезных ненадежных оптимизаций. Как время и истощение приводит к его постоянно старению философия "MC/ASM" перед слишком нетерпеливым поколением "Microsoft", программистов больше не считают хорошо осведомленными или достаточно ответственными для создания этого вида из решения. Вместо изобретенных многих, для не высказывания творческий реализации я засвидетельствовал как руководитель проекта, это ни в коем случае не плохая вещь.

Хотя это сообщение быстро развивается во вне темы нарушение, я чувствую себя несколько доказанным постоянным потоком нисходящих связанных вопросов, которые медленно становятся местными в нашей промышленности. Как неоперившийся программист C - язык, первоначально разработанный для дополнения разработки низкого уровня - мой совет состоит в том, чтобы принять подход снизу вверх и увеличить исследования с небольшой внеучебной разработкой ассемблера. Поскольку алгоритмическая реализация, вероятно, составит Ваше основное внимание как инженера приложений, важно помнить, что современный дизайн ЦП испытал гомогенную эволюцию за прошлые 30 лет; сегодняшний сверхбыстрый Intel CPUs является не больше, чем суперскалярными улучшениями CMOS 4/8-bit биполярных процессоров, которые я программировал, когда Земля была все еще молода.

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

Удача с Вашими исследованиями.

5
ответ дан 2 December 2019 в 03:29
поделиться

Насколько я знаю, постоянные строки реализованы как массивы постоянных символов (или, в терминах C, const char [length]). Поэтому Вы не можете изменить его символы.

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

char* str = (char*)malloc(sizeof(char) * 4);
strcpy(str, "abc");
str[3] = '\0';

Конечно, не забывайте освобождать память в конце своей программы.


Править: Я не отправлю ничего связанного с инвертированием строки, потому что это - Ваша работа.

1
ответ дан 2 December 2019 в 03:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: