The problem (which I think you understand) is that you're storing a pointer to the same character array as input_line. In other words, the string inside history and input_line are the same data.
The solution is to make a copy of the input_line and storing that into the history. A naïve implementation (which will not work) is as follows:
int make_history(char *history[], int history_counter, char *input_line)
{
if(history_counter < HISTORY_MAX)
{
char input_copy[MAX];
strcpy(input_copy, input_line);
history[history_counter] = input_copy;
}
return 1;
}
Now, you're making a copy of the line into memory that isn't used anywhere else (input_copy). That should work, right? The problem is that declaring a variable like that (called static allocation) stores the variable's data on the stack. When a function returns, all the data that was put in the stack by that function is destroyed. When make_history() returns, input_copy is destroyed, and since history[history_counter] was pointing to the same array as input_copy, it's now pointing to a bit of memory that's probably going to be used for other purposes by the program and won't contain your copy of the input line any more.
You can use dynamic allocation to get around the issue of statically allocated memory existing only in the scope it is declared in. malloc() allocates memory on what's called the heap (in C; in C++ you'd use new). Data in the heap doesn't get destroyed while the program is running unless you tell it to free the memory yourself. Example:
int make_history(char *history[], int history_counter, char *input_line)
{
if(history_counter < HISTORY_MAX)
{
char *input_copy = (char *)malloc(MAX * sizeof(char));
strcpy(input_copy, input_line);
history[history_counter] = input_copy;
}
return 1;
}
This will work, since data in the heap (allocated by malloc()) will survive after make_history() returns and until either you free that memory yourself, or the program ends. Note how I use sizeof(char)—this is because primitive types (e.g. int, char) can differ in size according to the kind of processor you're compiling for, the compiler you're using, etc. (EDIT: Just a note, sizeof(char) == 1 is defined by the C specification (I think all revisions), and all other data type sizes are given in multiples of char.)
But what if:
// history_counter == 0
make_history(history,history_counter,input_line);
// ...
// later, when history_counter == 0 again somehow
make_history(history, history_counter, another_input_line);
All the second make_history() did was change a pointer from the copy of input_line to the copy of another_input_line! It never frees the memory of the first input_line, and now all the pointers to it have disappeared. That's called a memory leak (and it would be wonderful if they were all that simple!). If this were possible in your program (say, you made history_counter loop back to 0), you would want to fix this. After you allocated that memory the first time, you can just reuse it, right?
int make_history(char *history[], int history_counter, char *input_line)
{
if(history_counter < HISTORY_MAX)
{
if(history[history_counter] == NULL)
{
history[history_counter] = (char *)malloc(MAX * sizeof(char));
}
strcpy(history[history_counter], input_line);
history[history_counter] = input_copy;
}
return 1;
}
Now you're checking if you had already stored a copy of a line in history[history_counter] before, and if not you malloc() the memory first. Either way, after that you copy input_line into the history array. (There's another problem with your code that will break this; see below.)
Another thing you should know about dynamic allocation, since that seems to be the subject we're on, is that to free memory that you allocated using malloc(), use free(). For C++, to free memory allocated using new, use delete.
Another possible solution, as mentioned by a comment to your question: you could statically allocate 10*256*sizeof(char) bytes in main() right off the bat. It's a simpler solution, but uses up that memory all the time instead of just when needed. Your example is simple and doesn't require that much memory, but in bigger/more complicated programs, that difference can matter.
By the way, a few issues in your code other than the question:
You never initialize history_counter in main(), so its initial value is undefined when you call make_history(). You should treat an uninitialized variable (declared, but no value assigned) as random—in reality, the value depends on processor/system, compiler, OS, and is nothing you should rely on. Therefore, the second line of main() should be:
int i, n, history_counter = 0;
Similarly, you declared history as:
char *history[HISTORY_MAX];
and you don't initialize that array of pointers to NULL values. Later on you check:
if(history[i] != NULL)
but you have no guarantee that the default value of history[i] is NULL for all i. You should initialize the history array to all NULL values first. My last example above for my actual answer also relies on this initialization being done, and bad things could happen if you try to free() an unallocated address.