argv[i]
являются не строками сами по себе, а указателями на области памяти, которые содержат текстовые строки.Это то, что вы делаете, когда говорите options[j] = malloc(...)
- вы выделяете область памяти, на которую указывает указатель.Но эта область памяти - просто область памяти, она не имеет ничего общего с указателем, за исключением того, что указатель указывает на нее.
Так что, когда вы говорите argv[i] = line_buf
, этоне означает копировать саму строку.Это означает изменение указателя, так что argv[i]
теперь указывает на ту же область памяти, где начинается line_buf[]
.Затем на следующей итерации цикла for
вы перезаписываете ту же область памяти.К концу цикла все десять ваших указателей указывают на line_buf
, который содержит последнюю строку вашего файла, поэтому вы получаете десять копий этой строки.
(Что также стоит отметитьявляется то, что когда readOptions () возвращает, та область памяти, на которую указывают все ваши указатели, считается неопределенной, потому что line_buf[]
только «существует» в функции readOptions (). Только благодаря удаче ваша программа печатает последнюю строкудесять раз вместо печати мусора или сбоя.)
Теперь, чтобы скопировать строку из одного места в другое, вы можете использовать функцию strcpy()
, которую можно добавить в вашу программу, поставив #include <string.h>
на вершине.Затем вы должны написать strcpy(argv[i], line_buf)
.
Вот как будет выглядеть простая версия strcpy (), чтобы вы могли увидеть, что она делает:
char *strcpy(char *dest, char *source) {
int i = 0;
while (source[i] != '\0') { /* a zero (or "null") byte means end of string */
dest[i] = source[i];
i=i+1;
}
dest[i] = source[i];
return dest;
}
Обратите внимание, что strcpy ()нет никакого способа узнать, сколько места есть, чтобы скопировать в!Если у вас недостаточно свободного места, оно пройдет сразу за конец вашего пространства и покажет, кто знает, в каких областях памяти может произойти сбой вашей программы или странное поведение.Это называется переполнением буфера, и это одна из самых распространенных ошибок безопасности.Поэтому убедитесь, что у вас достаточно места перед вызовом strcpy ().