Странное расположение в памяти аргументов функции с неизвестным количество аргументов - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Не могу понять, почему такая программа не работает, выдавая segmentation fault после распечатки первой строки:
Листинг программы
  1. void makeArr(char *str, ...)
  2. {
  3. char **p = &str;
  4. puts(*p);
  5. puts(*(p+1));
  6. puts(*(p+2));
  7. puts(*(p+3));
  8. }
  9. int main(void)
  10. {
  11. makeArr("a", "bm", "cdg", "ytttttt", NULL);
  12. return 0;
  13. }
Но если поменять сдвиг, на 3, то все начинает работать:
Листинг программы
  1. void makeArr(char *str, ...)
  2. {
  3. char **p = &str;
  4. puts(*p);
  5. puts(*(p+4));
  6. puts(*(p+5));
  7. puts(*(p+6));
  8. }
  9. int main(void)
  10. {
  11. makeArr("a", "bm", "cdg", "ytttttt", NULL);
  12. return 0;
  13. }
Я же правильно понимаю, что аргументы должны идти в памяти друг за другом? Их размер по 8 байт, т.к. 64 разрядная система и указатели, но арифметика указателей сама это учитывает. Но откуда же берется сдвиг и как его узнать нормально? Возможно, это связанно с компьютером, на котором компилируется программа. У меня Ubuntu, x64. Компилирую обычным gcc в консоли.

Решение задачи: «Странное расположение в памяти аргументов функции с неизвестным количество аргументов»

textual
Листинг программы
  1. void makeArr(char *str, ...)
  2. {
  3.     char* p = NULL;
  4.     va_list ap;
  5.     puts(str);
  6.     va_start(ap, str);
  7.     while(p = va_arg(ap, char*))
  8.         puts(p);
  9.     va_end(ap);
  10. }
  11. ...
  12. makeArr("a", "bm", "cdg", "ytttttt", NULL);

Объяснение кода листинга программы

В данном коде реализована функция makeArr, которая принимает два аргумента: строку и переменное количество аргументов типа char*. Далее в функции происходит следующее:

  1. char* p = NULL; - инициализируется указатель p с начальным значением NULL.
  2. va_list ap; - инициализируется список аргументов ap.
  3. puts(str); - выводится строка str.
  4. va_start(ap, str); - начинается проход по списку аргументов.
  5. В цикле while(p = va_arg(ap, char*)) происходит получение следующего аргумента типа char* и его вывод с помощью puts(p).
  6. va_end(ap); - заканчивается проход по списку аргументов. В основной части программы вызывается функция makeArr с аргументами a, bm, cdg, ytttttt, NULL.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

12   голосов , оценка 4.167 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы