-1

hi i need to do something like filesystem and i need to write and read from file (the write function work) i have a function signature

void read(int addr, int size, char *ans);

void BlockDeviceSimulator::read(int addr, int size, char *ans) {
    memcpy(ans, filemap + addr, size);
}

and this is my function to read from file and print it

    std::string MyFs::get_content(std::string path_str) {

        std::string ans;
//open file
        BlockDeviceSimulator *newFile = new BlockDeviceSimulator(path_str);
        newFile->read(1,newFile->DEVICE_SIZE,(char*)&ans);
        std::cout << ans << std::endl;
        delete newFile;
        return "";
    }

can you help me what is wrong here and why it dosen't print?

d.z
  • 11
  • 3
  • `ans.c_str()` seems appropriate. – William Pursell Mar 28 '20 at 13:24
  • 2
    Does this answer your question? [Is it possible to use an std::string for read()?](https://stackoverflow.com/questions/10105591/is-it-possible-to-use-an-stdstring-for-read) – a1ezh Mar 28 '20 at 13:42
  • No, because i think the error is in my call to read in the address but i dont know how to fix it – d.z Mar 28 '20 at 13:49

1 Answers1

1

You are trying to cast address of std::string object to pointer to char. At first you need to allocate enough size to read into std::string - ans.resize(newFile->DEVICE_SIZE);. Secondly you need to get char * from std::string - &ans[0].

a1ezh
  • 412
  • 3
  • 10
  • 1
    a1ezh and @d.z: std::string has a function for getting the address of the internal buffer: [`.data()`](https://en.cppreference.com/w/cpp/string/basic_string/data). That's more idiomatic that `&ans[0]`, although C++11 does define that `data() + i == std::addressof(operator[](i))` for every i in `[0, size()]` so this is guaranteed safe in C++11. I'm not *sure* `&ans[0]` is even safe in earlier C++; e.g. I think it could maybe break an older std::string that does lazy copy-on-write only when you call non-const `.data()`. – Peter Cordes Mar 28 '20 at 15:27
  • 1
    @PeterCordes `data()` (as like as `c_str()`) returns `const CharT*` in C++11 and `CharT*` only since C++17 (only `data()`). Thus `reference operator[]` is more universal. It is better to use `std::vector` in pre C++11. It guarantees to be sequential. – a1ezh Mar 28 '20 at 16:07
  • @a1ezh: Ah, you're right. The mention of only some overloads being const in that cppreference page only applies to C++17. But [`operator[]` is also UB in C++11 and later](https://en.cppreference.com/w/cpp/string/basic_string/operator_at): *For the first (non-const) version, the behavior is undefined if this character is modified to any value other than `CharT()`* and C++20 changes it to returning a `constexpr` reference – Peter Cordes Mar 28 '20 at 16:24
  • I guess you're supposed to read into some other buffer and then use `std::string::replace` or constructor. That touches twice as much memory and means you need to allocate another buffer somehow, but `.resize()` would still have wasted time zeroing memory before the read() call. I hate that C++ std::vector and st::string make it so hard to allocate a buffer for `read()`-like system calls and functions without wasting time zero-initializing it. Like the only way to use them efficiently is if everything uses `.push_back` instead of being passed a pointer+length. – Peter Cordes Mar 28 '20 at 16:27