7 Ağustos 2020 Cuma

std::memcpy metodu

Giriş
source ve destination alanları çakışamaz. Açıklaması şöyle. Bu tür problemlerle uğraşmamak için belki en iyisi her zaman memmove() metodunu kullanmak.
The memcpy() function copies n bytes from memory area src to memory area dest. The memory areas must not overlap. Use memmove(3) if the memory areas do overlap.
İmzası şöyle.
void *memcpy (void *restrict dest, const void restrict *src, size_t n);
Açıklaması şöyle.
The memcpy function returns the value of dest
Overlap Meselesi
Örnek - overlap
Şöyle yaparsak yanlış olur. Çünkü okuma yaptığımız alan ile yazma yaptığımız alan arr[2] bölgesinde çakışıyor.
char arr[10];
// Code that does something
memcpy(&arr[0], &arr[3], 5);
Ama bu kod yanlış değildir.
memcpy(&arr[0], &arr[3], 2);
Örnek
Doğru ve yanlış memcpy kullanımı. Şöyle yaparız.
char a[16];
char b[16];

memcpy(a,b,16);           // valid
memmove(a,b,16);          // Also valid, but slower than memcpy.
memcpy(&a[0], &a[1],10);  // Not valid since it overlaps.
memmove(&a[0], &a[1],10); // valid. 
Kullanım
Örnek
Aynı tipten iki nesne birbirine kopyalanabilir. Şöyle yaparız.
T* t1p;
T* t2p;
// provided that t2p points to an initialized object ...
std::memcpy(t1p, t2p, sizeof(T));
// at this point, every subobject of trivially copyable type in *t1p contains
// the same value as the corresponding subobject in *t2p
Örnek
Nesne char buffer'a kopylanabilir. Şöyle yaparız.
#define N sizeof(T)
char buf[N];
T obj;                    // obj initialized to its original value
std::memcpy(buf, &obj, N);// between these two calls to std​::​memcpy, obj might be modified
std::memcpy(&obj, buf, N);// at this point, each subobject of obj of scalar type holds
                          //its original value
Örnek
Açıklaması şöyle.
Copies count bytes from the object pointed to by src to the object pointed to by dest. Both objects are reinterpreted as arrays of unsigned char.
Nesne aynı veya daha büyük bir alana kopyalanabilir. Şöyle yaparız.
float f = ...;
uint32_t i;
static_assert(sizeof(f)==sizeof(i));
std::memcpy(&i, &f, sizeof(i));
// use i to extract f's sign, exponent & significand
Örnek
float* buffer'a double yazmak için şöyle yaparız.
void set(float *buffer, size_t index, double value) {
  memcpy(reinterpret_cast<char*>(buffer)+sizeof(double)*index, &value, sizeof(double));
}
double get(const float *buffer, size_t index) {
  double v;
  memcpy(&v, reinterpret_cast<const char*>(buffer)+sizeof(double)*index, sizeof(double));
  return v;
}
void f(float *buffer) {
  // here, use set and get functions
}
Copy Constructor Olarak memcpy 
Şu kod yanlıştır.
class A{
  public:
    int ID;
    virtual A* copy(){
      return new A();
    }
}

class B : public A{
  public:
    int subID;
    virtual A* copy(){
      B* b = new B();
      memcpy (b,this,sizeof(B));
      return b;
    }
};
Şöyle bir hata alırız.
destination for this 'memcpy' call is a pointer to dynamic class 'B' ;
 vtable pointer will be overwritten
explicitly cast the pointer to silence this warning
Açıklaması şöyle
C++ objects should not be copied with the C library's memcpy() function (except in certain limited situations), which knows nothing about C++ classes, their constructors, destructors, virtual methods, and everything else that's in C++ that's not in C.