pointer value change C++ [duplicate]












5
















This question already has an answer here:




  • Can a local variable's memory be accessed outside its scope?

    19 answers




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.










share|improve this question













marked as duplicate by πάντα ῥεῖ c++
Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Feb 19 at 17:45


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • 7





    Use std::string (when possible) for your own sanity.

    – jweyrich
    Feb 19 at 13:52






  • 2





    Inside the input function the variable buff is a local variable. Its life-time ends when the function ends, and in a way cease to exist. All pointers you save to that variable will be stray pointers and can't be dereferenced.

    – Some programmer dude
    Feb 19 at 13:53











  • Apart from the lifetime of buff issue, you'll also have a problem if any input of more than 19 characters (without whitespace) is encountered because operator >> with a right hand side argument of type char * will then clobber the following memory. This can be prevented by setting the stream's width() appropriately, e.g. cin >> std::setw(20) before every input to buff. The use of std::string is still widely considered better, however. (Starting from C++20, the library will be able to use the deduced size of the char array – one less thing to worry about.)

    – Arne Vogel
    Feb 19 at 16:28


















5
















This question already has an answer here:




  • Can a local variable's memory be accessed outside its scope?

    19 answers




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.










share|improve this question













marked as duplicate by πάντα ῥεῖ c++
Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Feb 19 at 17:45


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • 7





    Use std::string (when possible) for your own sanity.

    – jweyrich
    Feb 19 at 13:52






  • 2





    Inside the input function the variable buff is a local variable. Its life-time ends when the function ends, and in a way cease to exist. All pointers you save to that variable will be stray pointers and can't be dereferenced.

    – Some programmer dude
    Feb 19 at 13:53











  • Apart from the lifetime of buff issue, you'll also have a problem if any input of more than 19 characters (without whitespace) is encountered because operator >> with a right hand side argument of type char * will then clobber the following memory. This can be prevented by setting the stream's width() appropriately, e.g. cin >> std::setw(20) before every input to buff. The use of std::string is still widely considered better, however. (Starting from C++20, the library will be able to use the deduced size of the char array – one less thing to worry about.)

    – Arne Vogel
    Feb 19 at 16:28
















5












5








5









This question already has an answer here:




  • Can a local variable's memory be accessed outside its scope?

    19 answers




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.










share|improve this question















This question already has an answer here:




  • Can a local variable's memory be accessed outside its scope?

    19 answers




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.





This question already has an answer here:




  • Can a local variable's memory be accessed outside its scope?

    19 answers








c++ arrays






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Feb 19 at 13:50









JackJack

291




291




marked as duplicate by πάντα ῥεῖ c++
Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Feb 19 at 17:45


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.









marked as duplicate by πάντα ῥεῖ c++
Users with the  c++ badge can single-handedly close c++ questions as duplicates and reopen them as needed.

StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;

$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');

$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Feb 19 at 17:45


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.










  • 7





    Use std::string (when possible) for your own sanity.

    – jweyrich
    Feb 19 at 13:52






  • 2





    Inside the input function the variable buff is a local variable. Its life-time ends when the function ends, and in a way cease to exist. All pointers you save to that variable will be stray pointers and can't be dereferenced.

    – Some programmer dude
    Feb 19 at 13:53











  • Apart from the lifetime of buff issue, you'll also have a problem if any input of more than 19 characters (without whitespace) is encountered because operator >> with a right hand side argument of type char * will then clobber the following memory. This can be prevented by setting the stream's width() appropriately, e.g. cin >> std::setw(20) before every input to buff. The use of std::string is still widely considered better, however. (Starting from C++20, the library will be able to use the deduced size of the char array – one less thing to worry about.)

    – Arne Vogel
    Feb 19 at 16:28
















  • 7





    Use std::string (when possible) for your own sanity.

    – jweyrich
    Feb 19 at 13:52






  • 2





    Inside the input function the variable buff is a local variable. Its life-time ends when the function ends, and in a way cease to exist. All pointers you save to that variable will be stray pointers and can't be dereferenced.

    – Some programmer dude
    Feb 19 at 13:53











  • Apart from the lifetime of buff issue, you'll also have a problem if any input of more than 19 characters (without whitespace) is encountered because operator >> with a right hand side argument of type char * will then clobber the following memory. This can be prevented by setting the stream's width() appropriately, e.g. cin >> std::setw(20) before every input to buff. The use of std::string is still widely considered better, however. (Starting from C++20, the library will be able to use the deduced size of the char array – one less thing to worry about.)

    – Arne Vogel
    Feb 19 at 16:28










7




7





Use std::string (when possible) for your own sanity.

– jweyrich
Feb 19 at 13:52





Use std::string (when possible) for your own sanity.

– jweyrich
Feb 19 at 13:52




2




2





Inside the input function the variable buff is a local variable. Its life-time ends when the function ends, and in a way cease to exist. All pointers you save to that variable will be stray pointers and can't be dereferenced.

– Some programmer dude
Feb 19 at 13:53





Inside the input function the variable buff is a local variable. Its life-time ends when the function ends, and in a way cease to exist. All pointers you save to that variable will be stray pointers and can't be dereferenced.

– Some programmer dude
Feb 19 at 13:53













Apart from the lifetime of buff issue, you'll also have a problem if any input of more than 19 characters (without whitespace) is encountered because operator >> with a right hand side argument of type char * will then clobber the following memory. This can be prevented by setting the stream's width() appropriately, e.g. cin >> std::setw(20) before every input to buff. The use of std::string is still widely considered better, however. (Starting from C++20, the library will be able to use the deduced size of the char array – one less thing to worry about.)

– Arne Vogel
Feb 19 at 16:28







Apart from the lifetime of buff issue, you'll also have a problem if any input of more than 19 characters (without whitespace) is encountered because operator >> with a right hand side argument of type char * will then clobber the following memory. This can be prevented by setting the stream's width() appropriately, e.g. cin >> std::setw(20) before every input to buff. The use of std::string is still widely considered better, however. (Starting from C++20, the library will be able to use the deduced size of the char array – one less thing to worry about.)

– Arne Vogel
Feb 19 at 16:28














3 Answers
3






active

oldest

votes


















9














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.






share|improve this answer


























  • I don't quite understand. You said: "buff ceases to exist as soon as the input function exists" From my understanding the variable buff lives until the input function returns?

    – ASMJunkie
    Feb 19 at 14:52











  • Yes, and once the input function returns, you have an array of pointers into a buffer that no longer exists, and whose storage can be overwritten at any time. This answer uses "exits" to mean the same as "returns", ie, control exits the input function and returns to the caller.

    – Useless
    Feb 19 at 14:55











  • @ASMJunkie I wrote that buff ceases to exist as soon as the input function exits (not exists). Perhaps a poor choice of words. :-)

    – Willis Blackburn
    Feb 20 at 12:17



















1















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.






share|improve this answer

































    0














    Think of the stack as being a large (but not unlimited) amount of memory. It is allocated and freed simply be moving the stack pointer down and up (the directions will depend on the hardware).



    Here's your code with some annotations.



    input(arg, i);
    // when you get here the stack pointer will have been moved up, freeing the space
    // that was allocated for 'buf' in 'input'

    // the space for 'j' could overwrite the space where 'buf' was
    for (int j = 0; j < i; j++) {
    // the calls to 'cout' and 'end;' could overwrite the space where 'buf was'
    cout << arg[j] << endl;
    }





    share|improve this answer






























      3 Answers
      3






      active

      oldest

      votes








      3 Answers
      3






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      9














      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.






      share|improve this answer


























      • I don't quite understand. You said: "buff ceases to exist as soon as the input function exists" From my understanding the variable buff lives until the input function returns?

        – ASMJunkie
        Feb 19 at 14:52











      • Yes, and once the input function returns, you have an array of pointers into a buffer that no longer exists, and whose storage can be overwritten at any time. This answer uses "exits" to mean the same as "returns", ie, control exits the input function and returns to the caller.

        – Useless
        Feb 19 at 14:55











      • @ASMJunkie I wrote that buff ceases to exist as soon as the input function exits (not exists). Perhaps a poor choice of words. :-)

        – Willis Blackburn
        Feb 20 at 12:17
















      9














      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.






      share|improve this answer


























      • I don't quite understand. You said: "buff ceases to exist as soon as the input function exists" From my understanding the variable buff lives until the input function returns?

        – ASMJunkie
        Feb 19 at 14:52











      • Yes, and once the input function returns, you have an array of pointers into a buffer that no longer exists, and whose storage can be overwritten at any time. This answer uses "exits" to mean the same as "returns", ie, control exits the input function and returns to the caller.

        – Useless
        Feb 19 at 14:55











      • @ASMJunkie I wrote that buff ceases to exist as soon as the input function exits (not exists). Perhaps a poor choice of words. :-)

        – Willis Blackburn
        Feb 20 at 12:17














      9












      9








      9







      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.






      share|improve this answer















      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.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Feb 19 at 14:20

























      answered Feb 19 at 13:54









      Willis BlackburnWillis Blackburn

      3,6201424




      3,6201424













      • I don't quite understand. You said: "buff ceases to exist as soon as the input function exists" From my understanding the variable buff lives until the input function returns?

        – ASMJunkie
        Feb 19 at 14:52











      • Yes, and once the input function returns, you have an array of pointers into a buffer that no longer exists, and whose storage can be overwritten at any time. This answer uses "exits" to mean the same as "returns", ie, control exits the input function and returns to the caller.

        – Useless
        Feb 19 at 14:55











      • @ASMJunkie I wrote that buff ceases to exist as soon as the input function exits (not exists). Perhaps a poor choice of words. :-)

        – Willis Blackburn
        Feb 20 at 12:17



















      • I don't quite understand. You said: "buff ceases to exist as soon as the input function exists" From my understanding the variable buff lives until the input function returns?

        – ASMJunkie
        Feb 19 at 14:52











      • Yes, and once the input function returns, you have an array of pointers into a buffer that no longer exists, and whose storage can be overwritten at any time. This answer uses "exits" to mean the same as "returns", ie, control exits the input function and returns to the caller.

        – Useless
        Feb 19 at 14:55











      • @ASMJunkie I wrote that buff ceases to exist as soon as the input function exits (not exists). Perhaps a poor choice of words. :-)

        – Willis Blackburn
        Feb 20 at 12:17

















      I don't quite understand. You said: "buff ceases to exist as soon as the input function exists" From my understanding the variable buff lives until the input function returns?

      – ASMJunkie
      Feb 19 at 14:52





      I don't quite understand. You said: "buff ceases to exist as soon as the input function exists" From my understanding the variable buff lives until the input function returns?

      – ASMJunkie
      Feb 19 at 14:52













      Yes, and once the input function returns, you have an array of pointers into a buffer that no longer exists, and whose storage can be overwritten at any time. This answer uses "exits" to mean the same as "returns", ie, control exits the input function and returns to the caller.

      – Useless
      Feb 19 at 14:55





      Yes, and once the input function returns, you have an array of pointers into a buffer that no longer exists, and whose storage can be overwritten at any time. This answer uses "exits" to mean the same as "returns", ie, control exits the input function and returns to the caller.

      – Useless
      Feb 19 at 14:55













      @ASMJunkie I wrote that buff ceases to exist as soon as the input function exits (not exists). Perhaps a poor choice of words. :-)

      – Willis Blackburn
      Feb 20 at 12:17





      @ASMJunkie I wrote that buff ceases to exist as soon as the input function exits (not exists). Perhaps a poor choice of words. :-)

      – Willis Blackburn
      Feb 20 at 12:17













      1















      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.






      share|improve this answer






























        1















        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.






        share|improve this answer




























          1












          1








          1








          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.






          share|improve this answer
















          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.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Feb 19 at 14:58

























          answered Feb 19 at 14:52









          UselessUseless

          44.2k55495




          44.2k55495























              0














              Think of the stack as being a large (but not unlimited) amount of memory. It is allocated and freed simply be moving the stack pointer down and up (the directions will depend on the hardware).



              Here's your code with some annotations.



              input(arg, i);
              // when you get here the stack pointer will have been moved up, freeing the space
              // that was allocated for 'buf' in 'input'

              // the space for 'j' could overwrite the space where 'buf' was
              for (int j = 0; j < i; j++) {
              // the calls to 'cout' and 'end;' could overwrite the space where 'buf was'
              cout << arg[j] << endl;
              }





              share|improve this answer




























                0














                Think of the stack as being a large (but not unlimited) amount of memory. It is allocated and freed simply be moving the stack pointer down and up (the directions will depend on the hardware).



                Here's your code with some annotations.



                input(arg, i);
                // when you get here the stack pointer will have been moved up, freeing the space
                // that was allocated for 'buf' in 'input'

                // the space for 'j' could overwrite the space where 'buf' was
                for (int j = 0; j < i; j++) {
                // the calls to 'cout' and 'end;' could overwrite the space where 'buf was'
                cout << arg[j] << endl;
                }





                share|improve this answer


























                  0












                  0








                  0







                  Think of the stack as being a large (but not unlimited) amount of memory. It is allocated and freed simply be moving the stack pointer down and up (the directions will depend on the hardware).



                  Here's your code with some annotations.



                  input(arg, i);
                  // when you get here the stack pointer will have been moved up, freeing the space
                  // that was allocated for 'buf' in 'input'

                  // the space for 'j' could overwrite the space where 'buf' was
                  for (int j = 0; j < i; j++) {
                  // the calls to 'cout' and 'end;' could overwrite the space where 'buf was'
                  cout << arg[j] << endl;
                  }





                  share|improve this answer













                  Think of the stack as being a large (but not unlimited) amount of memory. It is allocated and freed simply be moving the stack pointer down and up (the directions will depend on the hardware).



                  Here's your code with some annotations.



                  input(arg, i);
                  // when you get here the stack pointer will have been moved up, freeing the space
                  // that was allocated for 'buf' in 'input'

                  // the space for 'j' could overwrite the space where 'buf' was
                  for (int j = 0; j < i; j++) {
                  // the calls to 'cout' and 'end;' could overwrite the space where 'buf was'
                  cout << arg[j] << endl;
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Feb 19 at 15:09









                  Paul FloydPaul Floyd

                  2,73421830




                  2,73421830















                      Popular posts from this blog

                      How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

                      is 'sed' thread safe

                      How to make a Squid Proxy server?