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.
Şöyle yaparsak yanlış olur. Çünkü okuma yaptığımız alan ile yazma yaptığımız alan arr[2] bölgesinde çakışıyor.
Doğru ve yanlış memcpy kullanımı. Şöyle yaparız.
Örnek
Aynı tipten iki nesne birbirine kopyalanabilir. Şöyle yaparız.
Nesne char buffer'a kopylanabilir. Şöyle yaparız.
Açıklaması şöyle.
float* buffer'a double yazmak için şöyle yaparız.
Şu kod yanlıştır.
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
ISO 1990 standardındaki açıklama şöyleydi. Yani destination parametresini dönüyordu
ReturnsThe memcpy function returns the value of s1
Açıklaması şöyle. Aynı çok eskiden her metod bir sonuç döndüğü için böyle yazmışlar
In early versions of the C language, every function would return something, whether or not the caller would make use of the returned value. Generally, the return value of a function would be whatever happened to be in some particular register of the appropriate type. If code exited a function without making any effort to set the register to something meaningful, and calling code ignored the contents of the register in question, having the function nominally return a meaningless value was simpler and easier than providing a means of having functions not return a value.
I don't think any particular thought was put into the question of what functions like memcpy, strcpy, or strcat should return, but the authors of the Standard didn't want to simply leave the return value unspecified. Since there may have been platforms where functions that don't return a value would be processed differently from those that do, giving such functions a void return type could have broken code that calls the functions without including the appropriate standard header.
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);
ÖrnekDoğ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
ÖrnekNesne 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
ÖrnekAçıklaması şöyle.
Nesne aynı veya daha büyük bir alana kopyalanabilir. Şöyle yaparız.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.
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
Örnekfloat* 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ı şöyleC++ 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.
Hiç yorum yok:
Yorum Gönder