I'm relatively new too C++ programming. While I was working on a code about arguments passing with an array of character pointers. I encountered a problem where the value of my pointers are changed after certain operations. Below is my code.
#include <iostream>
using namespace std;
void input(char* argv[], int &i)
{
char buff[10][20]; //buffer string array
while (cin.peek() != '\n') {
cin >> buff[i++];
}
for (int j = 0; j < i; j++) {
argv[j] = buff[j];
}
argv[i] = NULL; // putting a NULL at the end
}
int main(int argc, char* argv[])
{
char *arg[10];
int i = 0;
input(arg, i); //input the arguments
for (int j = 0; j < i; j++) {
cout << arg[j] << endl; //output the arguments entered
}
return 0;
}
The sub-function void input(char* argv[], int &i)
is supposed to let me input my arguments as many as 9 times or when an enter key is pressed. While i
indicates the total number of arguments.
The arguments are then stored as an array of character pointers and then pass it back to the main function's char *arg[10]
to hold.
However, I found that after
cout << arg[j] << endl;
The values of arg
are lost, and random values are being printed.
the value of my pointers are changed
The pointers are the only things that weren't damaged. The problem is the memory they point to.
You can prove the first part by printing the value of each of these pointers, or just inspecting them in the debugger. (You can print the address rather than the C-string it points to by casting to void, like cout << static_cast<void*>(arg[j]) << '\n'
).
So what happened to your C strings? Well, you declared an automatic-scope array variable inside the function input
. That array ceases to exist when the function exits, just like any other automatic-scope variable. Accessing the memory where a variable used to live, after the variable ceases to exist, is illegal.
The fact that you returned pointers into this array doesn't make it legal to read through (dereference) them after the array itself goes out of scope, and this is in fact undefined behaviour.
The contents being overwritten is actually the best case, because it meant you noticed the bug: it could legally have crashed or, even worse, appeared to work flawlessly until after you submitted/deployed/sold the program, and crashed every run thereafter.
You're creating a two-dimensional array of characters buff
on the stack, and then you're returning pointers into that array through the argv
parameter. But buff
lives on the stack and ceases to exist as soon as the input
function exits. The memory used by buff
will be overwritten by other functions that you call after calling input
.
You should allocate buff
in main
and then pass it into input
so it continues to live in the scope of main
after input
returns.
Another option would be to allocate heap space for buff
in input
. In this case the main
function would be responsible for freeing the memory after it was done with it.
Obviously there are more advanced C++ features you could use to avoid some of this overhead. Though this is a C++ program, it's effectively written as C. But understanding how memory and pointers work is essential to understanding the problems that the newer C++ features solve.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With