0

I've got the following code, and it seems to be printing gibberish. However, when I change the size of the array from "r" to 5000, it works perfectly. Can anyone explain this behavior and show me how to fix it? I've done a lot of research on this, but can't find an answer.

#include <iostream>
#include <cstring>
using namespace std;
int * check (int leng)
{
    const int r = leng;
    int arr [r]; 
    memset(arr,0,sizeof(arr)); 
    int * x = arr; 
    return x;
}    
main()
{
    int * l = check(20); 
    for (int g=0; g<5; g++) cout << l[g] << ' '; 
}
missimer
  • 4,022
  • 1
  • 19
  • 33
Man Patel
  • 3
  • 3
  • Related: http://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope – M.M Jun 19 '15 at 00:30

2 Answers2

2

x is the address of arr and arr is a stack variable so you cannot pass it as a return value. If you want check to return a pointer to an array you need to allocate it with new: arr = new int[r]. Note that you will need to eventually free the memory via delete[] For more info about dynamic memory allocation you can check out this link.

missimer
  • 4,022
  • 1
  • 19
  • 33
  • That allocated it on the stack and that is why you cannot use it outside that function. You most likely want to allocate it from the heap, see my updated answer. – missimer Jun 19 '15 at 00:06
  • Declaring an array outside the function would technically work in this simple case but it would mean that the function always returns the same array and is also just bad programming style. Also since the input to the function is the length of the array that wouldn't really work, the length argument would have to be removed. – missimer Jun 19 '15 at 00:13
  • @esm oh right, i overlooked the purpose of the function is to create and assign a new array, not modify an existing one. – Ediac Jun 19 '15 at 00:25
0

As you've discovered, allocating a variable on the stack and returning a pointer to that memory will likely result in garbage. The stack gets used and re-used with each series of function calls, so the memory allocated by your function will be re-used for different purposes by other function calls. You need to allocate the memory to be used outside of your function, either as a static allocation outside of any function, or else as a dynamic allocation. One way to handle this is:

#include <iostream>
#include <cstring>
using namespace std;
int * check (int leng)
{
    const int r = leng;
    int *x = new int [r]; 
    memset(x, 0, r * sizeof(int)); 
    return x;
}    
main()
{
    int * l = check(20); 
    for (int g=0; g<5; g++) cout << l[g] << ' '; 
    delete l;
}

Note that in check the memory for l is allocated dynamically with the new operator, and in main that memory is subsequently released with the delete operator. Failure to do the latter will result in a memory leak; in this case the leak would be minor as it would only occur once, and the memory space for the program would be reclaimed when the program exited, but in general it's good to get in the habit of releasing any and all allocated memory.

Best of luck.