В чем разница между «жестким кодированием»? и передать аргументы в отношении памяти?

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

В качестве примера я буду использовать конструктор для ifstream

Какая разница между этим:

void function(){

ifstream infile("home/some/file/path");

}

против

void function(char* filePath){

ifstream infile(filePath); //filePath points to a character array which contains home/some/file/path

}

Могут ли какие-либо последствия для памяти возникнуть из-за использования одного над другим? (Многопоточность может привести к повреждению кучи, если char * не свободен и правильно? И т. Д.).

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

1

Решение

Литералы (это то, что показывает ваш первый пример) помещаются в часть статической инициализации исполняемого файла (поэтому, если вы работаете в системе * Nix), вы можете использовать команду strings и получить список всех литералов в приложении.

Ваш второй пример должен быть изменен на

void function(const char* filePath) { ... }

Если вы не собираетесь изменять указатель в функции. Память для этой функции может поступать откуда угодно (строковый литерал, передаваемый в функцию, постоянная строка, объявленная где-то еще в приложении, строка, хранящаяся в памяти и вводимая из командной строки или консоли и т. Д.)

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

2

Другие решения

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

Является ли ваш второй вариант «хорошим», «плохим» или «ничего из вышеперечисленного», в значительной степени зависит от того, каково происхождение filePath является.

Понятно, если какой-то код делает char *filename = new char [x]; strcpy(filename, "..."); тогда должен быть соответствующий delete [] filename; — и x должен быть достаточно длинным для строки "..." подходить.

Безопаснее использовать std::string в этом случае, как и любое распределение, выполняется классом, а удаление — в деструкторе.

Если мы добавляем потоки в уравнение, нам также придется беспокоиться о том, где определены строки. В классе, который имеет только один экземпляр, как глобальная переменная или в стеке. Только «стек» является безопасным, и с ограничениями: если вы передаете указатель на char * от main [или какая-то другая функция перед созданием потока] в потоке, вы можете получить всевозможные «забавы», когда память выделяется несколько раз в одну строку, данные перезаписываются другими потоками и что у вас есть. Конечно, если потоки не меняют данные, также нет проблем с глобальной переменной или стеком вне потока.

Это то, что я имел в виду, «это зависит от того, как создается строка». Детали, безусловно, имеют значение здесь.

1

«Жестко» или буквальный значения обычно являются частью инструкций программы. Например, если я делаю что-то вроде

int i = 0;

значение 0 загружается с помощью команд сборки на архитектурном уровне. Так что я имею в виду, что они обрабатываются компилятором и программой и, вероятно, либо вообще не будут использовать память, либо будут находиться в стеке.

Для таких значений, как char *, во-первых, я бы порекомендовал использовать строки, так как они соответственно распределяют память, но большие строки часто хранятся в куче, в то время как маленькие строки (менее 7 символов или около того) могут быть оптимизированы для обрабатывается в стеке (если не указано «new»).

0
По вопросам рекламы [email protected]