C++ ve vektör/listelerinden önceki günlerde, daha fazla veri depolaması gerektiğinde dizilerin boyutunu nasıl genişlettiler?Vektör c içinde nasıl kopyalanır?
cevap
Tipik C kodu şuna benzer: Maalesef
oldMem = realloc(oldMem, newSize);
if(!oldMem)
{
// handle error
}
: realloc sıfır döndürür ama eski bellek hala geçerlidir ardından başarısız olursa, bu tipik kullanım bellek sızıntısına neden olduğunu
void* newMem = realloc(oldMem, newSize);
if(!newMem)
{
// handle error
}
oldMem = newMem;
Not çok yaygındır; Ayrıca, C++ vektörü/listesi hakkında özel bir şey olmadığını unutmayın. Benzer yapılar C dilinde uygulanabilir, sadece sözdizimi (ve hata işleme) farklı görünür. Örneğin, C.
için std :: vektörünün LodePNG's analoguna bakınız. C gibi birçok proje bir vektör benzeri API uygular. Dinamik diziler yaygın bir ihtiyaçtır, bellek yönetimini mümkün olduğunca soyutlamak güzeldir. onlar vector
üzerinde işlem çeşitli API işlev çağrıları olurdu Sonra
typedef struct dynamic_array_struct
{
int* data;
size_t capacity; /* total capacity */
size_t size; /* number of elements in vector */
} vector;
:
int vector_init(vector* v, size_t init_capacity)
{
v->data = malloc(init_capacity * sizeof(int));
if (!v->data) return -1;
v->size = 0;
v->capacity = init_capacity;
return 0; /* success */
}
Sonra tabii ki, push_back
için fonksiyonları ihtiyaç , insert
, resize
gibi tipik bir C uygulaması görünebilir realloc
'u arayarak, size
capacity
'u aşarsa Bir yeniden tahsis gerektiğinde
vector_resize(vector* v, size_t new_size);
vector_push_back(vector* v, int element);
Genellikle, capacity
her zaman yeniden tahsis önlemek için iki katına çıkarılır. Bu genellikle, std::vector
tarafından dahili olarak kullanılan aynı stratejidir, genellikle C++ nesnesi yapısı/imhası nedeniyle realloc
numaralı telefonu arayamaz. Bunun yerine, std::vector
, yeni bir arabellek tahsis edebilir ve daha sonra yapıyı/taşı kopyala (yeni yerleşimi new
kullanarak) yeni arabelleğe oluşturur.
C'deki gerçek bir vektör uygulaması, int
yerine öğeler olarak void*
işaretçileri kullanabilir, bu nedenle kod daha geneldir. Her neyse, bu tür şeyler çok sayıda C projesinde uygulanmaktadır. Örnek bir vektör uygulaması için bakınız: http://codingrecipes.com/implementation-of-a-vector-data-structure-in-c C.
Burada yapınızın veri değişkeni için bir işaretçi oluşturuyor gibi görünüyorsun. vektör uygulamaları çevrimiçi Ben yapının veri değişkeni bir çift işaretçi tarafından tutulduğunu gördüm. Bu iki yol arasındaki fark nedir? – Kai
Link bozuk, bkz. Https://gist.github.com/EmilHernvall/953968/0fef1b1f826a8c3d8cfb74b2915f17d2944ec1d0 ne için popüler bir uygulama gibi görünüyor –
Uygulama için gerekli üyeleri tutacak bir yapı tanımlayarak gizlemeye başlayacaklardır. Daha sonra yapının içeriğini manipüle edecek bir fonksiyon grubu sağlayın. Böyle
şey: Bunların ötesinde
typedef struct vec
{
unsigned char* _mem;
unsigned long _elems;
unsigned long _elemsize;
unsigned long _capelems;
unsigned long _reserve;
};
vec* vec_new(unsigned long elemsize)
{
vec* pvec = (vec*)malloc(sizeof(vec));
pvec->_reserve = 10;
pvec->_capelems = pvec->_reserve;
pvec->_elemsize = elemsize;
pvec->_elems = 0;
pvec->_mem = (unsigned char*)malloc(pvec->_capelems * pvec->_elemsize);
return pvec;
}
void vec_delete(vec* pvec)
{
free(pvec->_mem);
free(pvec);
}
void vec_grow(vec* pvec)
{
unsigned char* mem = (unsigned char*)malloc((pvec->_capelems + pvec->_reserve) * pvec->_elemsize);
memcpy(mem, pvec->_mem, pvec->_elems * pvec->_elemsize);
free(pvec->_mem);
pvec->_mem = mem;
pvec->_capelems += pvec->_reserve;
}
void vec_push_back(vec* pvec, void* data, unsigned long elemsize)
{
assert(elemsize == pvec->_elemsize);
if (pvec->_elems == pvec->_capelems) {
vec_grow(pvec);
}
memcpy(pvec->_mem + (pvec->_elems * pvec->_elemsize), (unsigned char*)data, pvec->_elemsize);
pvec->_elems++;
}
unsigned long vec_length(vec* pvec)
{
return pvec->_elems;
}
void* vec_get(vec* pvec, unsigned long index)
{
assert(index < pvec->_elems);
return (void*)(pvec->_mem + (index * pvec->_elemsize));
}
void vec_copy_item(vec* pvec, void* dest, unsigned long index)
{
memcpy(dest, vec_get(pvec, index), pvec->_elemsize);
}
void playwithvec()
{
vec* pvec = vec_new(sizeof(int));
for (int val = 0; val < 1000; val += 10) {
vec_push_back(pvec, &val, sizeof(val));
}
for (unsigned long index = (int)vec_length(pvec) - 1; (int)index >= 0; index--) {
int val;
vec_copy_item(pvec, &val, index);
printf("vec(%d) = %d\n", index, val);
}
vec_delete(pvec);
}
onlar fonksiyon grubu için vec * yerine boşluk * kullanarak kapsülleme ulaşmak ve aslında içinde tanımlayarak kullanıcıdan yapı tanımını saklanırdın başlık yerine işlev grubunu içeren C modülü. Ayrıca, özel olarak düşünmeyi düşündüğünüz işlevleri, başlıktan çıkartarak ve yalnızca C modülünde sadece prototipleme yaparak gizlerler.
struct vc_vector {
size_t count;
size_t element_size;
size_t reserved_size;
char* data;
vc_vector_deleter* deleter;
};
...
vc_vector* vc_vector_create_copy(const vc_vector* vector) {
vc_vector* new_vector = vc_vector_create(vector->reserved_size/vector->count,
vector->element_size,
vector->deleter);
if (unlikely(!new_vector)) {
return new_vector;
}
if (memcpy(vector->data,
new_vector->data,
new_vector->element_size * vector->count) == NULL) {
vc_vector_release(new_vector);
new_vector = NULL;
return new_vector;
}
new_vector->count = vector->count;
return new_vector;
}
Kullanmak için:
Bunu 30 dakika içinde yazdı, garanti yok. –
Sen uygulama vc_vector görebilirsiniz
vc_vector* v1 = vc_vector_create(0, sizeof(int), NULL);
for (int i = 0; i < 10; ++i) {
vc_vector_push_back(v1, &i);
}
// v1 = 0 1 2 3 4 5 6 7 8 9
vc_vector* v2 = vc_vector_create_copy(v1);
// v2 = 0 1 2 3 4 5 6 7 8 9 (copy of v1)
// to get pointer to int:
const int* v2_data = vc_vector_data(v1);
- 1. Rcpp içinde minimum vektör bulun
- 2. C++ empty std :: vektör,
- 3. Vektör içinde STL
- 4. Dosya Kaynaklar nasıl kopyalanır?
- 5. C++ liste/vektör yardım
- 6. Dizi davranışı nasıl kopyalanır?
- 7. Vektör simge, C++
- 8. sizeof() std :: vektör (C++)
- 9. Eclipse'deki bir panoya nasıl kopyalanır?
- 10. std :: vektör eki nasıl uygulanır? C++
- 11. C# ile vektör türünü nasıl alabilirim?
- 12. Oracle'da kullanıcı nasıl kopyalanır
- 13. Bir UIImage nasıl kopyalanır?
- 14. Dosya nasıl kopyalanır?
- 15. .xib dosyası nasıl kopyalanır?
- 16. CouchDB'den PouchDB'ye nasıl kopyalanır?
- 17. boş bir vektör döndürün C++
- 18. TextField OSX panosuna nasıl kopyalanır?
- 19. Dizinler, bash içinde yükleme kullanılarak bir dizine nasıl kopyalanır?
- 20. Vektör
- 21. sıfırlara bir vektör başlatmak C++/C++ 11
- 22. Çok satırlı bir metin kutusunun içeriğini C# panoya nasıl kopyalanır?
- 23. İçinde vektör grafikleri olan bir düğme oluşturma
- 24. nasıl SIMD vektör
- 25. Python bytearray arabelleği nasıl kopyalanır?
- 26. Javascript'te panoya nasıl metin kopyalanır?
- 27. SKSpriteNode SKPhysicsBody ile nasıl kopyalanır?
- 28. Özel karakterler html'de nasıl kopyalanır?
- 29. C# içinde marshal nasıl *?
- 30. Bir tutulma dinamik web projesi nasıl kopyalanır?
serin vay, C++ eşdeğer Böylece whats? Örneğin. malloc = yeni, ücretsiz = sil, realloc =? – Kaije
@ user: Eşdeğerleriniz yanlış. Bunlar: malloc = vektör :: vektör, serbest = vektör :: temizle, realloc = vektör :: yeniden boyutlandır. – ybungalobill
@ybungalobill, um ... 'vektör :: temizle() '' özgür' için hiçbir şekilde gerçek anlamda değildir. –