0

I'm trying to read an array from a file that has the arrays contents stored in a comma delimited list on a single very long line (about 346112 elements long).

I have a function that works sometimes, then other times it fails with a segmentation fault (core dump) error.

What is wrong with this code?

int* read(std::string fileName)
{
    std::ifstream input(fileName.c_str());
    std::string line; 

    getline(input, line);
    std::string str = line;

    std::vector<int> vect;
    std::stringstream ss(str);

    int i = 0;
    while (ss >> i)
    {

        vect.push_back(i);
        if (ss.peek() == ',')
            ss.ignore();
    }
    input.close();

    return &vect[0];
}

Then I call it like this:

int* h_w1 = NULL;
h_w1 = (int*)malloc(sizeof(int) * 346112);
h_w1 = read("file.txt");

What the heck is wrong with this code?

user8919
  • 67
  • 2
  • 9
  • Given `std::vector vect;` doesn't `return &vect[0];` return the address of a stack variable? – Andrew Henle Jul 18 '17 at 17:11
  • Those last 3 lines are very suspicious (and leaking memory) – Borgleader Jul 18 '17 at 17:11
  • 1
    @AndrewHenle No, but it still isnt correct. The vector will go out of scope and delete its dynamically allocated memory so returning a pointer to it is incorrect. – Borgleader Jul 18 '17 at 17:13
  • I have the return value like that to "copy" the data from the vector into an array. I saw in another post this is a trick that seems to work. I don't really need to use a vector at all. This is just the best method I have found so far. Reading from file in C is a nightmare! So I'm trying to use some of the C++ stuff (not effectively clearly). – user8919 Jul 18 '17 at 17:14
  • 1
    Instead of doing what youre doing now, read the file into the vector and keep the vector around, whenever you need the pointer to the first element call `.data()` – Borgleader Jul 18 '17 at 17:17
  • Good call Borgleader. However I use the data right after that to copy the contents over to an FPGA via OpenCL. I am finding that I can't use any C++ with OpenCL on an Altera FPGA device code - I can only use C. – user8919 Jul 18 '17 at 17:20
  • 1
    Sure, not in OpenCL, what I mean is return the vector from that function and when you need to transfer the data to OpenCL then call .data() to get `int*`. – Borgleader Jul 18 '17 at 17:32
  • The thing is `h_w1 = read("file.txt");` is only copying a pointer, not the data, and the pointer is invalid by the time you get it. You'd need to keep the vector around or something more like `read("file.txt", h_w1);` and appropriate modifications to `read` to either copy the data in the vector into the `h_w1` or read directly into `h_w1`. Keeping the vector and using `data` is probably an order of magnitude or two easier. – user4581301 Jul 18 '17 at 17:39
  • Wow. I see. So I guess I might as well return a vector and then use the .data() function to copy the contents of the vector into an array like Borleader is saying. – user8919 Jul 18 '17 at 17:47
  • Why do you need to copy the data into another array? I thought you were sending it to an FPGA? – Borgleader Jul 18 '17 at 17:49
  • I cant send a vector to the FPGA. I can't call anything from the standard library or really use any C++ when I pass data from the CPU to the FPGA in OpenCL. I can use C++ in the "host" code, but once I need to transfer data to the "device" I can only use C. So I am reading into a vector (to make the reading part easier) then copying the contents into an array then passing those contents over to the FPGA. Do you know of a better method Borgleader? I am very new to OpenCL. – user8919 Jul 18 '17 at 17:59
  • Well, [the one question](https://stackoverflow.com/questions/12426061/how-to-pass-and-access-c-vectors-to-opencl-kernel) I saw on transferring a vector to opencl didnt do any copies, so I think something [like this](http://coliru.stacked-crooked.com/a/e209893b72d21123) should work (I faked the OpenCL call because I dont have the includes). (P.S: I also made the read function shorter) – Borgleader Jul 18 '17 at 18:04
  • That person seems to be using a version of OpenCL newer than version 1.0. They are almost certainly using a GPU (as most people use OpenCL for GPU programming similar to CUDA). The Intel OpenCL FPGA SDK is only fully compatible with OpenCL 1.0. Note that the Intel OpenCL FPGA SDK is different than the Intel OpenCL SDK (which is for CPUs and their co-processors other than FPGAs). I very much wish I was able use C++, but FPGAs are very limited in their ease of programability - but this is much better than classical FPGA programming via Verilog! – user8919 Jul 18 '17 at 18:10
  • @Borgleader *No, but it still isnt correct. The vector will go out of scope and delete its dynamically allocated memory so returning a pointer to it is incorrect.* That makes sense, but wouldn't it be an implementation-specific detail, though? It's the reference to the address of something *in* the vector - *how* it goes bad would be an "implementation detail". (I try to avoid the internal implementation details of standard C++ library objects...) – Andrew Henle Jul 18 '17 at 18:15
  • Also, thanks for the code Borgleader. I am trying it out now. :) – user8919 Jul 18 '17 at 18:16
  • @AndrewHenle I think the term you're looking for is undefined behavior. – Borgleader Jul 18 '17 at 18:17
  • @Borgleader Thanks, But aren't you the one who specified the failure mode here? ;-) – Andrew Henle Jul 18 '17 at 18:22
  • @AndrewHenle No? I explained why it was incorrect. AFAIK since C++11 SVO is no longer viable so the vector has to use dynamically allocated memory, regardless, when the vector goes out of scope whether the memory is dynamically allocated or not the problem is the same you have a stale pointer and accessing it is UB. – Borgleader Jul 18 '17 at 18:25
  • @Borgleader Thank you tremendously! It works. You are awesome! – user8919 Jul 18 '17 at 18:41

0 Answers0