C dinamik olarak büyüyen dizi


126

Oyun içi varlıkların "ham" listesini okuyan bir programım var ve çeşitli şeyleri işlemek için belirsiz sayıda varlığın indeks numarasını (int) tutan bir dizi yapmak niyetindeyim. Bu tür dizinleri saklamak için çok fazla bellek veya CPU kullanmaktan kaçınmak istiyorum ...

Şimdiye kadar kullandığım hızlı ve kirli bir çözüm, ana işleme işlevinde (yerel odak) maksimum oyun varlıklarının boyutuna sahip bir dizi ve listeye kaç tane eklendiğini takip etmek için başka bir tamsayı bildirmektir. Her liste 3000'den fazla dizi içerdiğinden, bu tatmin edici değil, bu o kadar da değil, ama bir israf gibi geliyor, çünkü çözümü çeşitli işlevler için 6-7 liste için kullanabilirim.

Bunu başarmak için C'ye (C ++ veya C # değil) özel çözümler bulamadım. İşaretçileri kullanabilirim, ancak onları kullanmaktan biraz korkuyorum (mümkün olan tek yol bu değilse).

Bir şeyleri değiştirmesi durumunda, diziler yerel işlev kapsamını terk etmezler (bir işleve iletilirler, sonra atılırlar).

İşaretçiler tek çözümse, sızıntıları önlemek için bunları nasıl takip edebilirim?


1
Bu, C'de (çok, çok küçük) bir sorundur, ancak bunun için tüm C ++ ve C # çözümlerini nasıl kaçırdınız?
Ignacio Vazquez-Abrams

11
"Eğer işaretçiler tek çözümse, sızıntıları önlemek için onları nasıl takip edebilirim?" Dikkat, dikkat ve değer. İşte bu yüzden insanlar ilk etapta C ise bu kadar korkuyorlar.
Chris Lutz

27
İşaretçiler kullanmadan C'yi etkili bir şekilde kullanamazsınız. Korkmayın.
qrdl

büyük
kitaplıklar

6
İşaretçiler olmadan C kullanmak, yakıtsız bir araba kullanmak gibidir.
martinkunev

Yanıtlar:


211

İşaretçileri kullanabilirim, ancak onları kullanmaktan biraz korkuyorum.

Dinamik bir diziye ihtiyacınız varsa, işaretçilerden kaçamazsınız. Yine de neden korkuyorsun? Isırmazlar (dikkatli olduğunuz sürece, yani). C'de yerleşik dinamik dizi yoktur, sadece kendiniz bir tane yazmanız gerekir. C ++ 'da yerleşik std::vectorsınıfı kullanabilirsiniz. C # ve diğer tüm yüksek seviyeli dillerin de sizin için dinamik dizileri yöneten benzer bir sınıfı vardır.

Kendi yazınızı yazmayı planlıyorsanız, işte başlamanız için bir şey var: çoğu dinamik dizi uygulaması, bazı (küçük) varsayılan boyutta bir dizi ile başlayarak çalışır, daha sonra yeni bir öğe eklerken alanınız bittiğinde, dizinin boyutu. Aşağıdaki örnekte görebileceğiniz gibi, hiç de zor değil: (Kısalık için güvenlik kontrollerini atladım)

typedef struct {
  int *array;
  size_t used;
  size_t size;
} Array;

void initArray(Array *a, size_t initialSize) {
  a->array = malloc(initialSize * sizeof(int));
  a->used = 0;
  a->size = initialSize;
}

void insertArray(Array *a, int element) {
  // a->used is the number of used entries, because a->array[a->used++] updates a->used only *after* the array has been accessed.
  // Therefore a->used can go up to a->size 
  if (a->used == a->size) {
    a->size *= 2;
    a->array = realloc(a->array, a->size * sizeof(int));
  }
  a->array[a->used++] = element;
}

void freeArray(Array *a) {
  free(a->array);
  a->array = NULL;
  a->used = a->size = 0;
}

Bunu kullanmak da çok basit:

Array a;
int i;

initArray(&a, 5);  // initially 5 elements
for (i = 0; i < 100; i++)
  insertArray(&a, i);  // automatically resizes as necessary
printf("%d\n", a.array[9]);  // print 10th element
printf("%d\n", a.used);  // print number of elements
freeArray(&a);

1
Örnek kod için teşekkürler. Büyük bir dizi kullanarak belirli bir işlevi uyguladım, ancak bunu kullanarak diğer benzer şeyleri uygulayacağım ve onu kontrol ettikten sonra diğerlerini geri değiştireceğim :)
Balkania

2
Kod için çok teşekkürler. removeArraySon unsurdan kurtulan bir yöntem de düzgün olacaktır. İzin verirseniz, kod örneğinize ekleyeceğim.
brimborium

5
% d ve size_t ... biraz hayır-hayır. C99 veya sonraki bir sürümünü kullanıyorsanız,% z eklenmesinden yararlanabilirsiniz
Randy Howard

13
Bellek ayırma ve yeniden atama ile güvenlik kontrollerini asla ihmal etmeyin.
Alex Reynolds

3
Bu bir performans değiş tokuşu. Her seferinde ikiye katlarsanız, bazen ek yükünüz% 100 ve ortalama olarak% 50 olur. 3/2 size% 50 en kötü ve% 25 tipik verir. Ayrıca, Fibionacci sekansının (phi) "üstel ancak taban-2'den çok daha az şiddetle" övülen ve kullanılan, ancak hesaplaması daha kolay olan etkili tabanına da yakındır. +8, oldukça küçük dizilerin çok fazla kopya yapmayacağı anlamına gelir. Çarpımsal bir terim ekler, dizinin boyutu alakasızsa hızlı bir şekilde büyümesini sağlar. Uzman kullanımlarında bu ayarlanabilir olmalıdır.
Dan Sheppard

11

İlk başta daha sonra olduğundan daha korkunç görünen her şeyde olduğu gibi, ilk korkuyu aşmanın en iyi yolu kendinizi bilinmeyenin rahatsızlığına kaptırmaktır ! Ne de olsa bazen en çok öğrendiğimiz şeydir.

Maalesef sınırlamalar var. Hâlâ bir işlevi kullanmayı öğrenirken, örneğin bir öğretmen rolünü üstlenmemelisiniz. Görünüşe göre nasıl kullanılacağını bilmeyenlerin realloc(yani şu anda kabul edilen cevap! ) Başkalarına yanlış bir şekilde nasıl kullanacaklarını söyleyen cevaplarını sık sık okurum, bu yaygın bir tuzak olmasına rağmen, bazen hata işlemeyi ihmal ettikleri kisvesi altında. bahsetmesi gereken. İşte nasıl kullanılacağını açıklayan bir cevap değil reallocdoğru . Hata kontrolü yapmak için cevabın dönüş değerini farklı bir değişkene kaydettiğine dikkat edin .

Bir işlevi her çağırdığınızda ve bir diziyi her kullandığınızda, bir işaretçi kullanırsınız. Dönüşümler örtük olarak gerçekleşiyor, bu da daha da korkutucu olmalı, çünkü genellikle en çok soruna neden olan, görmediğimiz şeylerdir. Örneğin bellek sızıntıları ...

Dizi operatörleri işaretçi operatörleridir. array[x]gerçekten bir kısayol *(array + x)olup, şu şekilde ayrılabilir: *ve (array + x). Büyük ihtimalle *kafanızı karıştıran şey budur. Biz ayrıca varsayarak problemden eklenmesini ortadan kaldırabilir xolmak 0, böylece array[0]olur *arrayekleyerek çünkü 0değerini değiştirmeyecektir ...

... ve böylece bunun *arrayeşdeğer olduğunu görebiliriz array[0]. Birini kullanmak istediğiniz yerde kullanabilirsiniz ve bunun tersi de geçerlidir. Dizi operatörleri işaretçi operatörleridir.

malloc, reallocVe arkadaşlar yok icat Eğer baştan beri kullanıyorum bir işaretçi kavramını; bunu yalnızca , boyutta şiddetli, dinamik değişiklikler istediğinizde en uygun olan, farklı bir depolama süresi biçimi olan başka bir özelliği uygulamak için kullanırlar .

Şu anda kabul edilen cevap bu utanç verici , aynı zamanda bir ters geliyor StackOverflow'daki diğer bazı çok sağlam temellere dayanan tavsiye ve aynı zamanda, tam da bu USECASE parlar az bilinen bir özelliği tanıtmak için bir fırsat kaçırır: Esnek dizi üyeler! Bu aslında oldukça bozuk bir cevap ... :(

Dizinizi tanımladığınızda, üst sınır olmadan yapının sonundastruct dizinizi bildirin. Örneğin:

struct int_list {
    size_t size;
    int value[];
};

Bu, dizinizi kendinizle intaynı ayırmada birleştirmenize olanak tanır countve bunların bu şekilde bağlanması çok kullanışlı olabilir !

sizeof (struct int_list)value0 boyutuna sahipmiş gibi davranacak , bu yüzden size yapının boyutunu boş bir liste ile söyleyecektir . reallocListenizin boyutunu belirtmek için geçilen boyutu yine de eklemeniz gerekir .

Başka bir kullanışlı ipucu da realloc(NULL, x)bunun eşdeğer olduğunu hatırlamaktır malloc(x)ve bunu kodumuzu basitleştirmek için kullanabiliriz. Örneğin:

int push_back(struct int_list **fubar, int value) {
    size_t x = *fubar ? fubar[0]->size : 0
         , y = x + 1;

    if ((x & y) == 0) {
        void *temp = realloc(*fubar, sizeof **fubar
                                   + (x + y) * sizeof fubar[0]->value[0]);
        if (!temp) { return 1; }
        *fubar = temp; // or, if you like, `fubar[0] = temp;`
    }

    fubar[0]->value[x] = value;
    fubar[0]->size = y;
    return 0;
}

struct int_list *array = NULL;

struct int_list **İlk argüman olarak kullanmayı seçmemin nedeni hemen açık görünmeyebilir, ancak ikinci argümanı düşünürseniz value, içeriden yapılan herhangi bir değişiklik, push_backçağırdığımız fonksiyon tarafından görünmez, değil mi? Aynısı ilk argüman için de geçerli ve bizim arraysadece burada değil, aynı zamanda muhtemelen onu aktardığımız diğer fonksiyonlarda da değiştirebilmeliyiz ...

arrayhiçbir şeye işaret etmeye başlar; bu boş bir listedir. İlklendirmek, ona eklemekle aynı şeydir. Örneğin:

struct int_list *array = NULL;
if (!push_back(&array, 42)) {
    // success!
}

Not: İşinizfree(array); bittiğinde bunu unutmayın!


" array[x]gerçekten *(array + x)[...] için bir kısayol " Bundan emin misiniz ???? Farklı davranışlarının bir açıklamasını görün: eli.thegreenplace.net/2009/10/21/… .
C-Star-W-Star

1
Ne yazık ki @ C-Star-Puppy, kaynağınızın hiç bahsetmediği tek referans C standardıdır. Bu, derleyicilerinizin yasal olarak kendilerine C derleyicileri olarak adlandırmak için uymaları gereken özelliktir. Kaynağınız bilgilerimle hiç çelişiyor gibi görünmüyor. Bununla birlikte, standart aslında gibi bazı örnekler vardır bu taş o ortaya oluyor array[index]aslında ptr[index]kılık değiştirmiş ... "simge operatöre tanımına []yani E1[E2]aynıdır (*((E1)+(E2)))" Std çürütmek olamaz
otistik

Bu gösteriyi deneyin, @ C-Star-Puppy: int main(void) { unsigned char lower[] = "abcdefghijklmnopqrstuvwxyz"; for (size_t x = 0; x < sizeof lower - 1; x++) { putchar(x[lower]); } }... Muhtemelen ihtiyacınız olacak #include <stdio.h>ve <stddef.h>... Nasıl yazdığımı görüyor musunuz x[lower]( xtam sayı türü olarak) değil lower[x]mi? C derleyicisi, çünkü bakım değildir *(lower + x)ile aynı değerlere sahiptir *(x + lower)ve lower[x]eski olduğu-olarak x[lower]ikincisidir. Tüm bu ifadeler eşdeğerdir. Onları deneyin ... sözümü
otistik

... ve sonra elbette, kendi vurguladığım bir bölüm var, ama gerçekten tüm alıntıyı vurgulamadan okumalısınız: "Sizeof operatörünün, _Alignof operatörünün veya tekli & işleci veya bir diziyi başlatmak için kullanılan bir dize değişmezi ise, '' dizi tipi '' türüne sahip bir ifade, dizinin ilk öğesine işaret eden '' tipe işaretçi '' türünde bir ifadeye dönüştürülür nesne ve bir değer değil . Dizi nesnesinin kayıt depolama sınıfı varsa, davranış tanımsızdır. " Aynısı işlevler için de geçerlidir, btw.
otistik

Ohh ve son bir not olarak, @ C-Star-Puppy, Microsoft C ++ bir C derleyicisi değil ve neredeyse 20 yıldır bir C derleyicisi değil. C89 modunu etkinleştirebilirsiniz, suuure , ancak bilgi işlemde 1980'lerin sonlarının ötesine geçtik. Bu konu hakkında daha fazlası için, ben okumanızı öneririz bu yazıyı ... sonra gibi gerçek bir C derleyicisi geçiş gccya clangsen C99 özellikleri benimsedik kadar çok paketler vardır bulacaksınız, çünkü C derleme tümü için ...
otistik

10

Aklıma gelen birkaç seçenek var.

  1. Bağlantılı liste. Dinamik olarak büyüyen bir dizi benzeri şey yapmak için bağlantılı bir liste kullanabilirsiniz. Ama önce array[100]yürümek zorunda kalmadan yapamayacaksın 1-99. Ve kullanmak sizin için o kadar da kullanışlı olmayabilir.
  2. Büyük dizi. Her şey için fazlasıyla yeterli alana sahip bir dizi oluşturun
  3. Dizi yeniden boyutlandırılıyor. Diziyi, boyutunu öğrendikten ve / veya bir miktar marjla alanınız her bittiğinde yeni bir dizi oluşturduğunuzda yeniden oluşturun ve tüm verileri yeni diziye kopyalayın.
  4. Bağlantılı Liste Dizisi kombinasyonu. Basitçe sabit boyutlu bir dizi kullanın ve alanınız tükendiğinde, yeni bir dizi oluşturun ve buna bağlantı verin (diziyi ve bir yapıdaki sonraki diziye olan bağlantıyı takip etmek akıllıca olacaktır).

Sizin durumunuzda hangi seçeneğin en iyi olacağını söylemek zor. Basitçe geniş bir dizi oluşturmak elbette en kolay çözümlerden biridir ve gerçekten büyük olmadığı sürece size fazla sorun çıkarmamalıdır.


Modern görünümlü bir 2D oyun için 3264 tam sayıdan oluşan yedi dizi nasıl ses çıkarır? Sadece paranoyak oluyorsam, çözüm geniş bir dizi olurdu.
Balkania

3
Burada hem # 1 hem de # 4, yine de işaretçiler ve dinamik bellek ayırma kullanımını gerektirir. realloc# 3 ile kullanmanızı öneririm - diziyi normal bir boyuta ayırın ve her bittiğinizde onu büyütün. reallocgerekirse verilerinizi kopyalayacaktır. OP'nin bellek yönetimi ile ilgili sorusuna gelince malloc, başlangıçta bir freekez, sonunda bir kez ve reallocher zaman yeriniz bittiğinde yapmanız gerekir. Fena değil.
Borealid

1
@Balkania: 3264 tam sayıdan oluşan yedi dizi, 100KB'nin altında bir saçtır. Bu çok fazla hafıza değil.
Borealid

1
@Balkania: 7 * 3264 * 32 bitGibi geliyor 91.39 kilobytes. Bugünlerde herhangi bir standarda göre o kadar değil;)
Wolph

1
Bu özel ihmal utanç verici, çünkü reallocgeri döndüğünde ne olacağı tam olarak belli değil NULL: a->array = (int *)realloc(a->array, a->size * sizeof(int));... Belki de en iyisi int *temp = realloc(a->array, a->size * sizeof *a->array); a->array = temp;şu şekilde yazılabilirdi: ... Bu şekilde olan her şeyin daha önce olması gerektiği aşikar olacaktır. NULLdeğer atanır a->array(hepsi de ise).
otistik

3

Bina Matteo Furlans hakkındaki sözleri, tasarım " yeni bir öğe eklerken en dinamik dizi uygulamaları bazı (küçük) varsayılan boyutta bir dizi kapalı başlatarak işe, o zaman dizinin boyutunu iki katına, alanı tükendi zaman ". Aşağıdaki "devam eden çalışma " daki fark, boyut olarak iki katına çıkmaması, sadece gerekli olanı kullanmayı amaçlamasıdır. Ayrıca basitlik için güvenlik kontrollerini de atladım ... Ayrıca brimboriums fikrinden yola çıkarak , koda bir silme işlevi eklemeye çalıştım ...

Storage.h dosyası şuna benzer ...

#ifndef STORAGE_H
#define STORAGE_H

#ifdef __cplusplus
extern "C" {
#endif

    typedef struct 
    {
        int *array;
        size_t size;
    } Array;

    void Array_Init(Array *array);
    void Array_Add(Array *array, int item);
    void Array_Delete(Array *array, int index);
    void Array_Free(Array *array);

#ifdef __cplusplus
}
#endif

#endif /* STORAGE_H */

Storage.c dosyası şuna benzer ...

#include <stdio.h>
#include <stdlib.h>
#include "storage.h"

/* Initialise an empty array */
void Array_Init(Array *array) 
{
    int *int_pointer;

    int_pointer = (int *)malloc(sizeof(int));

    if (int_pointer == NULL)
    {       
        printf("Unable to allocate memory, exiting.\n");
        free(int_pointer);
        exit(0);
    }
    else
    {
        array->array = int_pointer; 
        array->size = 0;
    }
}

/* Dynamically add to end of an array */
void Array_Add(Array *array, int item) 
{
    int *int_pointer;

    array->size += 1;

    int_pointer = (int *)realloc(array->array, array->size * sizeof(int));

    if (int_pointer == NULL)
    {       
        printf("Unable to reallocate memory, exiting.\n");
        free(int_pointer);
        exit(0);
    }
    else
    {
        array->array = int_pointer;
        array->array[array->size-1] = item;
    }
}

/* Delete from a dynamic array */
void Array_Delete(Array *array, int index) 
{
    int i;
    Array temp;
    int *int_pointer;

    Array_Init(&temp);

    for(i=index; i<array->size; i++)
    {
        array->array[i] = array->array[i + 1];
    }

    array->size -= 1;

    for (i = 0; i < array->size; i++)
    {
        Array_Add(&temp, array->array[i]);
    }

    int_pointer = (int *)realloc(temp.array, temp.size * sizeof(int));

    if (int_pointer == NULL)
    {       
        printf("Unable to reallocate memory, exiting.\n");
        free(int_pointer);
        exit(0);
    }
    else
    {
        array->array = int_pointer; 
    } 
}

/* Free an array */
void Array_Free(Array *array) 
{
  free(array->array);
  array->array = NULL;
  array->size = 0;  
}

Main.c şuna benzer ...

#include <stdio.h>
#include <stdlib.h>
#include "storage.h"

int main(int argc, char** argv) 
{
    Array pointers;
    int i;

    Array_Init(&pointers);

    for (i = 0; i < 60; i++)
    {
        Array_Add(&pointers, i);        
    }

    Array_Delete(&pointers, 3);

    Array_Delete(&pointers, 6);

    Array_Delete(&pointers, 30);

    for (i = 0; i < pointers.size; i++)
    {        
        printf("Value: %d Size:%d \n", pointers.array[i], pointers.size);
    }

    Array_Free(&pointers);

    return (EXIT_SUCCESS);
}

Yapıcı eleştiriyi takip etmek için sabırsızlanıyoruz ...


1
Yapmak istediğiniz yapıcı eleştiri ise, Code Review'de yayınlamak daha iyidir . Bununla birlikte, birkaç öneri: kodun malloc(), tahsisi kullanmaya başlamadan önce çağrıların başarısını kontrol etmesi zorunludur . Aynı şekilde, realloc()işaretçinin sonucunu yeniden tahsis edilen orijinal belleğe doğrudan atamak da bir hatadır ; realloc()başarısız olursa, NULLdöndürülür ve kodda bir bellek sızıntısı kalır . Yeniden boyutlandırırken belleği iki katına çıkarmak, bir seferde 1 boşluk eklemekten çok daha etkilidir: daha az çağrı realloc().
ex nihilo

1
Parçalanacağımı biliyordum, "yapıcı eleştiri"

2
Kimseyi parçalamaya çalışmıyorum, sadece biraz yapıcı eleştiriler sunuyorum, bu biraz daha yakın yürekli olmadan bile ortaya çıkmış olabilir;)
ex nihilo

1
David, "Yeniden boyutlandırırken hafızayı iki katına çıkarmak, bir seferde 1 boşluk eklemekten çok daha etkilidir: realloc () için daha az çağrı". Bunu benim için detaylandırır mısın lütfen, neden sadece görev için gerekli miktarı tahsis etmektense iki kat bellek ayırıp kullanmamak, dolayısıyla belleği boşa harcamak daha iyidir? Realloc () çağrıları hakkında söylediklerinizi anlıyorum, ancak her sorun olduğunda neden realloc () çağrısı yapılıyor? Belleği yeniden tahsis etmek için var olan bu değil mi?

1
Kesin ikiye katlama optimal olmasa da, hafızayı inther seferinde bir bayt (veya bir bayt , vb.) Artırmaktan kesinlikle daha iyidir . İkiye katlama tipik bir çözümdür, ancak tüm koşullara uyan optimum bir çözüm olduğunu düşünmüyorum. İşte iki katına çıkarmanın iyi bir fikir olmasının nedeni şudur (1.5 gibi başka bir faktör de iyi olabilir): makul bir tahsisatla başlarsanız, yeniden tahsis etmeniz gerekmeyebilir. Daha fazla belleğe ihtiyaç duyulduğunda, makul ayırma iki katına çıkar ve bu böyle devam eder. Bu şekilde, muhtemelen yalnızca bir veya iki aramaya ihtiyacınız olacaktır realloc().
ex nihilo

2

Söylediğin zaman

belirsiz sayıda varlığın dizin numarasını (int) tutan bir dizi yapmak

temelde "işaretçiler" kullandığınızı söylüyorsunuz, ancak bellek genişliğinde işaretçi yerine dizi çapında yerel işaretçi kullanıyorsunuz. Kavramsal olarak zaten "işaretçiler" (yani bir dizideki bir öğeyi ifade eden kimlik numaraları) kullandığınız için, neden yalnızca normal işaretçiler kullanmıyorsunuz (yani en büyük dizideki bir öğeye atıfta bulunan kimlik numaraları: tüm bellek ).

Nesnelerinizin bir kaynak kimlik numarası depolaması yerine, bunun yerine bir işaretçi depolamalarını sağlayabilirsiniz. Temelde aynı şey, ancak "dizi + indeksi" bir "işaretçi" ye dönüştürmekten kaçındığımız için çok daha verimli.

İşaretçiler, onları tüm bellek için dizi indeksi olarak düşünürseniz korkutucu değildir (gerçekte oldukları şey budur)


2

Her türden sınırsız öğe dizisi oluşturmak için:

typedef struct STRUCT_SS_VECTOR {
    size_t size;
    void** items;
} ss_vector;


ss_vector* ss_init_vector(size_t item_size) {
    ss_vector* vector;
    vector = malloc(sizeof(ss_vector));
    vector->size = 0;
    vector->items = calloc(0, item_size);

    return vector;
}

void ss_vector_append(ss_vector* vec, void* item) {
    vec->size++;
    vec->items = realloc(vec->items, vec->size * sizeof(item));
    vec->items[vec->size - 1] = item;
};

void ss_vector_free(ss_vector* vec) {
    for (int i = 0; i < vec->size; i++)
        free(vec->items[i]);

    free(vec->items);
    free(vec);
}

ve nasıl kullanılacağı:

// defining some sort of struct, can be anything really
typedef struct APPLE_STRUCT {
    int id;
} apple;

apple* init_apple(int id) {
    apple* a;
    a = malloc(sizeof(apple));
    a-> id = id;
    return a;
};


int main(int argc, char* argv[]) {
    ss_vector* vector = ss_init_vector(sizeof(apple));

    // inserting some items
    for (int i = 0; i < 10; i++)
        ss_vector_append(vector, init_apple(i));


    // dont forget to free it
    ss_vector_free(vector);

    return 0;
}

Bu vektör / dizi her tür öğeyi tutabilir ve boyut olarak tamamen dinamiktir.


0

Sanırım, bir öğeyi kaldırmanız gerekirse, dizinin, hariç tutulacak öğeyi küçümseyen bir kopyasını yapacaksınız.

// inserting some items
void* element_2_remove = getElement2BRemove();

for (int i = 0; i < vector->size; i++){
       if(vector[i]!=element_2_remove) copy2TempVector(vector[i]);
       }

free(vector->items);
free(vector);
fillFromTempVector(vector);
//

Varsayalım getElement2BRemove(), copy2TempVector( void* ...)ve fillFromTempVector(...)geçici vektörü işlemek için yardımcı yöntemlerdir.


Bunun aslında sorulan soruya bir cevap mı yoksa bir yorum mu olduğu belli değil.

Bu "nasıl yapılır" ile ilgili bir fikir ve ben onay istiyorum (Yanılıyor muyum?) EĞER birinin daha iyi bir fikri varsa. ;)
JOSMAR BARBOSA - M4NOV3Y

Sanırım son cümlenizi anlamıyorum. SO iş parçacıklı bir forum olmadığından, yanıtlarda buna benzer açık sorular tuhaf görünüyor.

1
Son cümlenizi söylemek istediğini düşündüğüm şeye ayarladım.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.