4

I have the following code in C++:

typedef struct 
{
   int age;
   int roomNumber;
} Student;

Student student;
student.age = 20;
student.roomNumber = 10;

vector<Student> studentV;
student.push_back(student);
student.push_back(student);
student.push_back(student);

Student student1[3];

int i;

for(vector<Student>::const_iterator iterator = studentV.begin();
    iterator != studentV.end(); ++iterator,++i)
{
   memcpy(&student1[i], iterator, sizeof(Student));
}

It show the following message for the memcpy part:

error: cannot convert 'std::vector<Student>::const_iterator {aka __gnu_cxx::__normal_iterator<const Student*, std::vector<Student> >}' to 'const void*' for argument '2' to 'void* memcpy(void*, const void*, size_t)'

What is the problem and how to fix it? is iterator can not be copied like this?

ratzip
  • 113
  • 2
  • 11

4 Answers4

4

The second argument of memcpy should be address of Student object, so you should use &*iterator instead of iterator. Because of operator overloading those two are not equivalent. But I would recommend not to use memcpy at all.

Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51
  • why not to use memcpy? then what to use? – ratzip Mar 27 '14 at 14:05
  • Using `memcpy` for structs copying is a low-level mechanism inherited from C. In C++ instead of your loop use `std::copy(studentV.begin(), studentV.end(), student1);` which is much simpler and makes many errors not possible - for instance in your code `i` is not initialised, which would cause undefined behaviour, while with `copy` you do not need any `i` at all. – Wojtek Surowka Mar 27 '14 at 14:11
4

What you want to do is copy what the iterator refers to. Use *iterator to get the object referenced by the iterator and & to get its address. By the way DO NOT use memcpy but the copy constructor:

student1[i] = *iterator;
neuro
  • 14,948
  • 3
  • 36
  • 59
2

You should take advantage of the actual C++11 facilities and avoid using memcpy at all:

#include <iostream>
#include <vector>
#include <array>

typedef struct
{
    int age;
    int roomNumber;
} Student;

int main() {
    Student student{ 20, 10 };
    std::vector<Student> studentV{ student, student, student };
    std::array<Student, 3> student1;

    if (studentV.size() <= student1.size())
        std::copy(studentV.begin(), studentV.end(), student1.begin());
    for (const auto& s : student1) {
        std::cout << s.age << " " << s.roomNumber << std::endl;
    }
}
Matthieu Poullet
  • 417
  • 1
  • 9
  • 20
0

Use std::copy algorithm. It will use plain memory copy routines (like memcpy) if the object is POD or will use copy constructor otherwise. If will also protect you from copying non-copyable objects (by printing an error during compilation), something your code may do and which may cause hard to trace errors (like double free inside copied non-copyable objects).

Tomek
  • 4,554
  • 1
  • 19
  • 19