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

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

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

Не могу понять, почему такая программа не работает, выдавая segmentation fault после распечатки первой строки:
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;
}
Но если поменять сдвиг, на 3, то все начинает работать:
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;
}
Я же правильно понимаю, что аргументы должны идти в памяти друг за другом? Их размер по 8 байт, т.к. 64 разрядная система и указатели, но арифметика указателей сама это учитывает. Но откуда же берется сдвиг и как его узнать нормально? Возможно, это связанно с компьютером, на котором компилируется программа. У меня Ubuntu, x64. Компилирую обычным gcc в консоли.

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

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*. Далее в функции происходит следующее:

  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
Похожие ответы