Прежде всего, благодарю вас за этот вопрос, у вас есть интересная морщина.
Я запустил ваш код с помощью Eclipse/Microsoft C и НЕ получил ошибку сегментации, и он напечатал «asdf», как ожидалось.
Однако это НЕ означает или подразумевает, что вы не получаете ошибку сегментации. Ваш результат предполагает изучение того, как компилятор реализует два заявления:
char *test3 = (char *) malloc(sizeof(char) * 5);
Выделяет память в куче и устанавливает указатель, test3
, чтобы указать на это место. Следующий оператор также обновляет тот же указатель.
test3 = "asdf";
Однако в этом случае test3
указывает на буквальное «Asdf» где-нибудь, что буквальное хранится. Некоторые компиляторы генерируют литеральный пул строк и хранят их где-то в исполняемом файле, поэтому для некоторых компиляторов эти литералы не могут быть изменены.
Так зачем компилятору хранить литерал, в котором он не может быть доступен? Не имеет смысла, поэтому вопрос: какой компилятор C вы используете? А какая версия C придерживается?
Чтобы обойти то, что может быть ошибкой компилятора, и все еще указать test3
на литерал, попробуйте ?? (Опять же, компиляторы действительно отличаются от того, что и как они реализуют языковые конструкции.)
const char *literal = "asdf"; // also try without a const stmt
// other code here
test3 = literal;
Наконец, во втором примере хранения в куче, которая была malloc
ред модифицируется и, очевидно, адресацией.
Вы уверены, что первый код-образец правильно скопирован, так как он не выглядит так, как будто он рушится ко мне ... Возможно, в вашем примере вы делали что-то еще, кроме как скопировать константу в 'test3' - например, попробуйте ALTER содержимое 'test3'? Или вы имеете в виду, что он падает, когда вы пытаетесь освободить 'test3'? –
Я удивлен, что вы даже можете сделать первый образец с современными компиляторами и их nixing, позволяющий назначать адреса const неконстантным указателям. Ваш первый образец также пропускает самую память, которую вы выделили в первой строке, путем перезаписи возвращаемого адреса на следующей строке. То есть вы пропустили память в двух коротких строках. Я согласен с Мэттом, вы, вероятно, рушитесь на 'free()' call * после * кода в первом примере, так как вы освобождаете const-память. – WhozCraig