Странное расположение в памяти аргументов функции с неизвестным количество аргументов - C (СИ)
Формулировка задачи:
Не могу понять, почему такая программа не работает, выдавая segmentation fault после распечатки первой строки:
Но если поменять сдвиг, на 3, то все начинает работать:
Я же правильно понимаю, что аргументы должны идти в памяти друг за другом? Их размер по 8 байт, т.к. 64 разрядная система и указатели, но арифметика указателей сама это учитывает. Но откуда же берется сдвиг и как его узнать нормально?
Возможно, это связанно с компьютером, на котором компилируется программа. У меня Ubuntu, x64. Компилирую обычным gcc в консоли.
void makeArr(char *str, ...)
{
char **p = &str;
puts(*p);
puts(*(p+1));
puts(*(p+2));
puts(*(p+3));
}
int main(void)
{
makeArr("a", "bm", "cdg", "ytttttt", NULL);
return 0;
}void makeArr(char *str, ...)
{
char **p = &str;
puts(*p);
puts(*(p+4));
puts(*(p+5));
puts(*(p+6));
}
int main(void)
{
makeArr("a", "bm", "cdg", "ytttttt", NULL);
return 0;
}Решение задачи: «Странное расположение в памяти аргументов функции с неизвестным количество аргументов»
textual
Листинг программы
void makeArr(char *str, ...)
{
char* p = NULL;
va_list ap;
puts(str);
va_start(ap, str);
while(p = va_arg(ap, char*))
puts(p);
va_end(ap);
}
...
makeArr("a", "bm", "cdg", "ytttttt", NULL);
Объяснение кода листинга программы
В данном коде реализована функция makeArr, которая принимает два аргумента: строку и переменное количество аргументов типа char*. Далее в функции происходит следующее:
char* p = NULL;- инициализируется указательpс начальным значениемNULL.va_list ap;- инициализируется список аргументовap.puts(str);- выводится строкаstr.va_start(ap, str);- начинается проход по списку аргументов.- В цикле
while(p = va_arg(ap, char*))происходит получение следующего аргумента типаchar*и его вывод с помощьюputs(p). va_end(ap);- заканчивается проход по списку аргументов. В основной части программы вызывается функцияmakeArrс аргументамиa,bm,cdg,ytttttt,NULL.