-2

I think I've got my self confused by following codes. Suppose I have two simple functions:

int* makeiniele()
{
    int res[55] = { 0 };
    return res;
}

and

void printele(int* wxyz)
{
    for (int k = 0; k < 55; k++)
    {
        cout << wxyz[k] << "\n";
    }
}

The problem is when I run the following line:

printele(makeiniele());

I get 55 big negative numbers instead of 55 zeros!

Thank you for your time

p.i.g.
  • 2,815
  • 2
  • 24
  • 41
Nop
  • 11
  • 1

3 Answers3

0

Two issues:

1) The array is not initialized to contain 55 zeros, but only 1, remaining 54 elements are going to be some older memory content:

int res[55] = { 0 };

you need to use the memset() function in order to do that efficiently:

int res[55];
memset(res, 0, sizeof(res));

2) The array you declare in the makeiniele() function will be deallocated after returning from the function and (since it was living on the stack) its content is going to be overwritten by the call of next function printele(). Therefore, initializing it correctly won't fix your problems.

A solution would be to consider using malloc() to allocate the array instead. Your makeiniele() function should look like this:

int* makeiniele(){
  int *res = malloc(sizeof(int)*55));
  memset(res, 0, sizeof(int)*55);
  return res;
}

And remember to call free() after you have finished with the array in order to avoid memory leaks.

simpel01
  • 1,792
  • 12
  • 13
  • Thanks, Now I got it. Just one thing: I just checked it; when I initialize first element to something ,c++ set the others to zero. – Nop Nov 21 '15 at 19:16
  • I don't think so. That would happen if you use one of the C++'s container types like `std::vector`, `std::array`. But I am pretty sure C++ does nothing in particular (regarding initialization) when using C arrays (like in your example). Unless you do the array allocation as a `static`, in that case the standard guarantees to be 0 initialized. – simpel01 Nov 21 '15 at 19:22
  • I see. One other question:when I'm using functions in this manner printele(makeiniele()) , how can I free memory for allocated memory in makeiniele? – Nop Nov 21 '15 at 19:31
  • Well, you can't. You can however call `free()` inside the print function after having printed its elements (given nobody else is going to need the array). – simpel01 Nov 21 '15 at 19:36
  • Since this question is tagged [tag:c++] I would suggest using `new`/`delete` instead of `malloc`/`free`. Or even using `shared_ptr` or `unique_ptr` – Zereges Nov 21 '15 at 21:08
0
int* makeiniele()
{
    int res[55] = { 0 };
    return res;
}

The problem here lies with scope - once a function ends, any variables declared within the function are deleted from memory. Once the function makeiniele terminates, the array res is also deleted from memory. The memory that array took up has been replaced with something else - this 'something else' is what's being printed to your screen. You can verify this with the following code:

int * myvar = new int[55]{ 0 };
int* var = myvar;
printele(var);
delete myvar;
printele(var);

The fist 55 numbers will be zeroes (the variable hasn't been deleted yet). Once the variable is manually deleted with delete the address of it is now pointing to unused memory, so it spits out random numbers. To fix this, replace your makeiniele funciton with this:

int* makeiniele()
{
    int * myvar = new int[55]{ 0 };
    return myvar;
}

And everything should work fine!

EDIT: As Zereges said, you MUST ensure to end your program with

delete myvar;

to prevent a memory leak.

otah007
  • 505
  • 1
  • 4
  • 17
0

A little modern C++ answer.

Either using clever array (std::vector)

std::vector<int> makeiniele()
{
    std::vector<int> res(55, 0);
    return std::move(res);
}

void printele(const std::vector<int>& wxyz)
{
    for (int k = 0; k < 55; k++)
    {
        cout << wxyz[k] << "\n";
    }
}

Or using clever pointers (std::shared_ptr)

std::shared_ptr<int> makeiniele()
{
    std::shared_ptr<int> res(new int[55]);
    std::memset(res.get(), 0, 55 * sizeof(int));
    return std::move(res);
}

void printele(std::shared_ptr<int> wxyz)
{
    for (int k = 0; k < 55; k++)
    {
        std::cout << wxyz.get()[k] << "\n";
    }
}
Zereges
  • 5,139
  • 1
  • 25
  • 49