3

When I try to convert a vector of integers to a array of integers inside a loop although within the loop the conversion appears to have worked, once the loop terminates the value within the array is incorrect.

I tried the std::copy instead of &vector[0] and the same problem arises. And I am aware that converting the vector to a array is not necessary. I assume the problem is due because the array is assigned a pointer to a variable which is destroyed after the loop, but i'm fairly new to c++ so even if I am correct I don't know how to fix it.

#include "pch.h"
#include <iostream>
#include <vector>

int main()
{
    int* arr;
    for (int i = 0; i < 1; i++)
    {
        std::vector<int> vec{ 1 };
        arr = &vec[0];
        std::cout << "Inside the loop in the vector: " << vec[0] << std::endl;
        std::cout << "Inside the loop in the array: " << arr[0] << std::endl;
    }
    std::cout << "Outside the loop in the array: " << arr[0];
}

I would expect the output to look like this:

Inside the loop in the vector: 1
Inside the loop in the array: 1
Outside the loop in the array: 1

But it actually turns out like this:

Inside the loop in the vector: 1
Inside the loop in the array: 1
Outside the loop in the array: -572662307

Finn Buhse
  • 33
  • 4
  • 3
    Possible duplicate of [Can a local variable's memory be accessed outside its scope?](https://stackoverflow.com/questions/6441218/can-a-local-variables-memory-be-accessed-outside-its-scope) – Algirdas Preidžius May 31 '19 at 13:10
  • @AlgirdasPreidžius it is not the access to a local var but the access to a freed block of memory in the heap – bruno May 31 '19 at 13:19
  • @bruno It's basically the same thing. – Lightness Races in Orbit May 31 '19 at 13:21
  • @bruno Yes, so? Even if example given is talking about the local variable, the underlying problem is the same. The block is freed, precisely, because one was trying to refer to it, outside of the scope, of its owning variable. – Algirdas Preidžius May 31 '19 at 13:24
  • @AlgirdasPreidžius I am afraid you will confuse more the OP more saying stack and heap are the same – bruno May 31 '19 at 13:25
  • better to refer to https://stackoverflow.com/questions/42588482/c-accessing-data-after-memory-has-been-freeed saying same thing in C and C++ – bruno May 31 '19 at 13:27
  • 1
    @bruno "_saying stack and heap are the same_" 1) I didn't state this. Don't put words in my mouth. 2) Technically, there is no such concepts as stack, or heap, in C++ standard, either. It's just those are typical implementations. – Algirdas Preidžius May 31 '19 at 13:28
  • @AlgirdasPreidžius undefined behavior is very typical implementations ^^ Heap and stack management are very different, OP case concerns heap, not stack – bruno May 31 '19 at 13:29
  • @bruno It's better to talk about the rules of the abstraction, than delve into implementation specifics like "freed block of memory in the heap". The pointer was logically invalidated when the vector went out of scope, causing a contract violation and UB. That's all we need to know! Don't confuse the OP with low-level OS implementation details that may or may not be true. – Lightness Races in Orbit May 31 '19 at 13:32
  • @LightnessRacesinOrbit I just say the OP does not understand the problem (this is why the OP ask for help) and to give a link to a problem associated to a local var is a risk to confuse the OP more, to give a link to a problem identical to the OP problem (so an access to a freed block in the heap) is better, that is all – bruno May 31 '19 at 13:36
  • @bruno: The vector is a local variable. It went out of scope. The OP then tried to use a resource that was owned by that variable. This is illegal. Period, end of story! – Lightness Races in Orbit May 31 '19 at 13:39
  • You will get different results in Release builds compared to Debug builds because the release build won't overwrite the stack where the local was the same way a Debug build will. Try it for fun. – Wyck May 31 '19 at 13:52
  • @LightnessRacesinOrbit by pity you know the contain of the vector is **not** in the stack so &arr[0] is in the heap rather than in the stack, so the invalid access will be in the heap, but you say the OP to look at the question "Can a local variable's memory be accessed outside its scope?" this is **ofc** a bad choice – bruno May 31 '19 at 13:53
  • 1
    @bruno The "local" part of that question title is not the point anyway. The Q&A is very informative and completely applicable. Let's agree to disagree. – Lightness Races in Orbit May 31 '19 at 13:56

2 Answers2

6

int* arr; <- This is a pointer, not an array.

std::vector<int> vec{ 1 }; <- This vector only exists within the body of your loop. That means, every iteration a new vector is created, and at the end of the iteration it is destroyed, freeing the memory it allocated.

arr = &vec[0]; <- This line doesn't copy anything, it simply sets the address that arr points to, to the first element in the vector's allocated memory.

Since your vector is destroyed after the loop, the address arr points to is invalid. As long as you are inside the loop, the address it points to is valid and you can safely access that memory.

You were right to try std::copy, however if you want to copy anything, you need to have memory allocated first that you can copy into. int arr[1]; would create an array of int with size 1, which can be used as the destination in std::copy. int* arr = new int[1]; would also work, but requires that you also free the memory later yourself (delete[] arr;). I wouldn't recommend managing memory yourself except for learning purposes.

Max Vollmer
  • 8,412
  • 9
  • 28
  • 43
1

The storage for vec[0] is freed when vec falls out of scope. You wouldn't expect a pointer to it to be valid outside the scope in which the vec variable lives.

I suggest you read this answer.

Wyck
  • 10,311
  • 6
  • 39
  • 60
  • the suggest answer is not adapted to the problem, it is not the access to a disappeared local var – bruno May 31 '19 at 13:20