For class I’m creating a shell in C++. It’s been a while since I’ve worked with C++ so I’m having a bit of trouble. One of the requirements for the project is that I must use the read() system call.
I’m required to keep a command history (similar to bash’s if you press the up arrow) that stores the most recent 20 commands. I feel the best way to do this is to use an array of pointers to previous statements. I’m running into a problem where no matter what I do, the string that contains the user input is always stored in the same location in memory. To clarify, this means, if a user inputs 5 statements and then views his/her history, they will see the most recent statement 5 times. My code looks a little something like this (I have to cut some things out because there is a lot of error handling in the middle):
char *history[20];
int historyCounter = 0;
while(true){
char currLine[65];
int charsRead = read(0,currLine,65);
char tmp[charsRead];
strcpy(tmp,currLine); //This is my attempt to ensure the char[] is stored int a
//unique location every time, but this attempt failed.
history[historycounter] = tmp;
historycounter++;
}
Just to note, in my source, I do handle the case when historycounter > 19. Just not in this snippet.
If any more clarification is required I’d be happy to provide it. This is my first time posting on stack overflow so I apologize in advance if I’m making any sort of rookie mistakes. I also apologize if the solution is painfully obvious. I’ve been looking at this for a while and it is entirely possible that I’m just not thinking straight.
In this case,
tmpis most likely to be in the same location, on stack. Its allocated every iteration, and deallocated when the iteration ends.The line
Will lead to undefined behavior when you use it because you’ll be using an address of a local variable outside of its scope.
If you want to ensure unique address (and solve the UB problem) – use
newto allocate the memory, and don’t usedeleteuntil you’re done. Make sure to keep track of all the allocated pointers anddeletethem when done.