В коментариях родилась задачка, которая на мой взгляд, вполне заслуживает оформления отдельным постом:
Есть код на языке C
#include
#include
void something_wrong() {
//(1)
char * p;
strcpy(p, "Hello");
printf("%s World\n", p);
}
void some_other_code() {
}
int main()
{
some_other_code();
something_wrong();
return 0;
}И
(
Read more... )
Comments 7
ну второй вопрос -- правильные ответы будут?
Reply
2) со временем :)
Reply
void something_wrong()
{
сhar x[6];
char * p = x;
strcpy(p, "Hello");
printf("%s World\n", p);
}
Исключая истерику компилятора по поводу strcpy, и то, что длина массива х подогнана руками, вроде как работает.
На "5" не претендую :) На "4" тоже.
Reply
Не пойдёт, надо было только добавить строку, а вы к определению p добавили его инициализацию
Reply
Вариант А, две строки
char arr[6];
#define p p=arr
Вариант Б, одна строка (не уверен что по стандарту компилятор обязан это пропустить):
#define p p=(__LINE__ == 5 ? (char*)malloc(6) : p)
Вариант В, одна строка:
char p[6]; //\
Вариант Г, сомнительный в смысле корректности, одна строка:
char arr[6]; char* q; (&q)[1] = arr;
На 5 баллов: если среда исполнения обещает не вклиниваться между вызовами, а компилятор выделяет память для локальных переменных идентичным образом, то может быть достаточно
void some_other_code() { static char arr[6]; char* p = arr; }
...но, по-моему, это нереальные требования, а как их ослабить - непонятно.
Reply
Б не пропускает компилятор, хотя он, как ни странно, наиболее близок к решению, которое мне кажется наиболее надежным. Но вы пошли не тем путем.
Вариант В интересен - но полностью убирает неинициализированный указатель, что скучно.
Ну и все варианты ломаются если мы не знаем длины копируемой строки.
Код на 5 баллов - верный. Требования как раз вполне реальные. gcc не пытается быть умнее человека и ведет себя так по дефолту, как впрочем и большинство компиляторов, поскольку порядок передачи параметров и работа со стеком для С стандартизованы.
Сделать это на MSVC в Debug невозможно совсем, поскольку он неявно инициализирует все указатели. В Release может и можно - но возиться с ключами компиляции мне лень - слишком неактуальная платформа.
Reply
Reply
Leave a comment