В чем разница между двумя случаями внутри функции?
Случай 1.
Как несколько человек сказал вам, последовательность
pch = strtok (tCpy,"=&");
/* ... */
pch= strtok (NULL, "&");
результаты в pch
быть указатель на локальный массив tCpy
(или NULL, если исходная строка не содержат либо '=', либо '&'). Поскольку tCpy
является локальным массивом, он выходит за пределы области действия в конце функции, после чего любые указатели на нее перестают быть действительными. На практике память, которую он занимает, вероятно, повторно используется следующей вызываемой функцией.
Случай 2.
Код
char *pp="Marcus";
инициализирует pp
, чтобы указать на статический, анонимный массив символов, содержимое которого являются завершающим нулем строку "Marcus"
. Поскольку массив имеет статическую продолжительность хранения, указатель на него остается действительным после выхода функции.
У вас есть три основных варианта работы вокруг этого вопроса:
- Вызывающий обеспечивает функцию предварительной выделенной памяти для копирования строки. Это может быть рабочий массив (необязательно динамически выделенный), или он может принимать форму просто позволить функции потреблять строку, а вызывающий вызывающий абонент несет ответственность за создание копии, если это необходимо.
- Функция распределяет память для копии динамически. Есть много способов, которые могут пойти, но функция
strdup()
- это быстрый и простой способ выделить и скопировать за один шаг.
- Вы можете сделать массив
tCpy
статическим. Тогда указатели на него останутся действительными после возврата из функции, но пространство будет использоваться повторно при каждом вызове этой функции, возможно, изменив текст, на который указывает указатель.
ПРИМЕЧАНИЕ ХОРОШО: любое изменение в функции выделения памяти для возврата к вызывающему дает ответственность вызывающего абонента для освобождая эту память, когда он больше не используется. Для этого требуется указатель на стартовый выделенного блока, а не на какое-то случайное место в середине, поэтому вам нужно будет передать два указателя для выполнения этой работы (один через аргумент).
Когда все будет сказано и сделано, я думаю, вам было бы разумно выбрать вариант варианта 1.Если бы это я, я бы просто позволил функции потреблять переданную ему строку.
UPDATE: Кроме того, в случае 2, программа изображение содержит данные ваши указатели указывают на. Предполагая, что он всегда загружается по тому же адресу, сохранение и восстановление значения указателя вместо того, что, по его мнению, может действительно работать только для этой программы, потому что вы повторно инициализируете отмеченную память, загружая изображение программы поверх нее. То же самое не применяется, если вы скопируете строку в рабочий массив, потому что хотя массив имеет статическую продолжительность, он не инициализируется данными, которые вы хотите восстановить.
'char l []' имеет автоматическую продолжительность хранения. Когда функция возвращается, конец жизни 'l' заканчивается, и любой доступ к ней является неопределенным поведением. Для его строки вам нужно хранить 'malloc()' хранилище, если вы хотите его вернуть. – EOF
Хорошо, спасибо большое! – aVC
@EOF Я обновил вопрос, чтобы показать свою настоящую проблему. Не могли бы вы взглянуть? Я работаю над платой arduino и использую библиотеку dueFlashStorage для записи значений в flash. Но эта функция дает мне проблемы в течение двух дней. – aVC