C dynamically growing arrayHow to read unknown number of floats from a file?Create a 2D Dynamic String ArrayReading in to a character array of unknown sizeHow do I define a dynamic array in CHow to create and use array without size limitation in C without dynamic memory allocation?How to dynamically set the size of char array CDo I cast the result of malloc?Resizing an array with CProper usage of realloc()Performance impact of realloc ()How do I determine the size of my array in C?How to initialize all members of an array to the same value?With arrays, why is it the case that a[5] == 5[a]?Fastest sort of fixed length 6 int arrayDesignated dynamic array initializationTrying to understand gcc option -fomit-frame-pointerIs a dynamic array of void pointers a performance concern for game development in C?Storing a Dynamic Array of StructuresHow to double the size of a dynamic array while keeping the old contentsHow to properly declare/initialize/finalize dynamic array of structs with other dynamic arrays

The Purpose of "Natu"

Was I wrongfully denied boarding for having a Schengen visa issued from the second country on my itinerary?

How important is it for multiple POVs to run chronologically?

Does the "divide by 4 rule" give the upper bound marginal effect?

Isn't "Dave's protocol" good if only the database, and not the code, is leaked?

Why is there paternal, for fatherly, fraternal, for brotherly, but no similar word for sons?

How do I iterate equal values with the standard library?

What exactly does "Stick Sensitivity" do in Smash Ultimate custom controls?

How would a sea turtle end up on its back?

Taking advantage when the HR forgets to communicate the rules

Is this car delivery via Ebay Motors on Craigslist a scam?

A positive integer functional equation

Is kapton suitable for use as high voltage insulation?

Should I warn my boss I might take sick leave?

What is the maximum amount of diamond in one Minecraft game?

How do I check that users don't write down their passwords?

What's the big deal about the Nazgûl losing their horses?

What is exact meaning of “ich wäre gern”?

Bypass with wrong cvv of debit card and getting OTP

Do intermediate subdomains need to exist?

How did Einstein know the speed of light was constant?

Is there a way to change the aspect ratio of a DNG file?

Should I cheat if the majority does it?

When is one 'Ready' to make Original Contributions to Mathematics?



C dynamically growing array


How to read unknown number of floats from a file?Create a 2D Dynamic String ArrayReading in to a character array of unknown sizeHow do I define a dynamic array in CHow to create and use array without size limitation in C without dynamic memory allocation?How to dynamically set the size of char array CDo I cast the result of malloc?Resizing an array with CProper usage of realloc()Performance impact of realloc ()How do I determine the size of my array in C?How to initialize all members of an array to the same value?With arrays, why is it the case that a[5] == 5[a]?Fastest sort of fixed length 6 int arrayDesignated dynamic array initializationTrying to understand gcc option -fomit-frame-pointerIs a dynamic array of void pointers a performance concern for game development in C?Storing a Dynamic Array of StructuresHow to double the size of a dynamic array while keeping the old contentsHow to properly declare/initialize/finalize dynamic array of structs with other dynamic arrays






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








115















I have a program that reads a "raw" list of in-game entities, and I intend to make an array holding an index number (int) of an indeterminate number of entities, for processing various things. I would like to avoid using too much memory or CPU for keeping such indexes...



A quick and dirty solution I use so far is to declare, in the main processing function (local focus) the array with a size of the maximum game entities, and another integer to keep track of how many have been added to the list.
This isn't satisfactory, as every list holds 3000+ arrays, which isn't that much, but feels like a waste, since I'll possible use the solution for 6-7 lists for varying functions.



I haven't found any C (not C++ or C#) specific solutions to achieve this. I can use pointers, but I am a bit afraid of using them (unless it's the only possible way).



The arrays do not leave the local function scope (they are to be passed to a function, then discarded), in case that changes things.



If pointers are the only solution, how can I keep track of them to avoid leaks?










share|improve this question

















  • 1





    This is a (very, very small) problem in C, but how did you miss all the C++ and C# solutions for this?

    – Ignacio Vazquez-Abrams
    Aug 21 '10 at 3:28






  • 9





    "If pointers are the only solution, how can I keep track of them to avoid leaks?" Care, attention, and valgrind. This is exactly why people are so afraid if C in the first place.

    – Chris Lutz
    Aug 21 '10 at 4:00






  • 19





    You cannot use C effectively without using pointers. Don't be afraid.

    – qrdl
    Aug 21 '10 at 4:17











  • without big libs only one function for all also for structs eg: stackoverflow.com/questions/3456446/…

    – user411313
    Aug 21 '10 at 6:45






  • 3





    Using C without pointers is like using a car without fuel.

    – martinkunev
    Dec 2 '17 at 9:48

















115















I have a program that reads a "raw" list of in-game entities, and I intend to make an array holding an index number (int) of an indeterminate number of entities, for processing various things. I would like to avoid using too much memory or CPU for keeping such indexes...



A quick and dirty solution I use so far is to declare, in the main processing function (local focus) the array with a size of the maximum game entities, and another integer to keep track of how many have been added to the list.
This isn't satisfactory, as every list holds 3000+ arrays, which isn't that much, but feels like a waste, since I'll possible use the solution for 6-7 lists for varying functions.



I haven't found any C (not C++ or C#) specific solutions to achieve this. I can use pointers, but I am a bit afraid of using them (unless it's the only possible way).



The arrays do not leave the local function scope (they are to be passed to a function, then discarded), in case that changes things.



If pointers are the only solution, how can I keep track of them to avoid leaks?










share|improve this question

















  • 1





    This is a (very, very small) problem in C, but how did you miss all the C++ and C# solutions for this?

    – Ignacio Vazquez-Abrams
    Aug 21 '10 at 3:28






  • 9





    "If pointers are the only solution, how can I keep track of them to avoid leaks?" Care, attention, and valgrind. This is exactly why people are so afraid if C in the first place.

    – Chris Lutz
    Aug 21 '10 at 4:00






  • 19





    You cannot use C effectively without using pointers. Don't be afraid.

    – qrdl
    Aug 21 '10 at 4:17











  • without big libs only one function for all also for structs eg: stackoverflow.com/questions/3456446/…

    – user411313
    Aug 21 '10 at 6:45






  • 3





    Using C without pointers is like using a car without fuel.

    – martinkunev
    Dec 2 '17 at 9:48













115












115








115


75






I have a program that reads a "raw" list of in-game entities, and I intend to make an array holding an index number (int) of an indeterminate number of entities, for processing various things. I would like to avoid using too much memory or CPU for keeping such indexes...



A quick and dirty solution I use so far is to declare, in the main processing function (local focus) the array with a size of the maximum game entities, and another integer to keep track of how many have been added to the list.
This isn't satisfactory, as every list holds 3000+ arrays, which isn't that much, but feels like a waste, since I'll possible use the solution for 6-7 lists for varying functions.



I haven't found any C (not C++ or C#) specific solutions to achieve this. I can use pointers, but I am a bit afraid of using them (unless it's the only possible way).



The arrays do not leave the local function scope (they are to be passed to a function, then discarded), in case that changes things.



If pointers are the only solution, how can I keep track of them to avoid leaks?










share|improve this question














I have a program that reads a "raw" list of in-game entities, and I intend to make an array holding an index number (int) of an indeterminate number of entities, for processing various things. I would like to avoid using too much memory or CPU for keeping such indexes...



A quick and dirty solution I use so far is to declare, in the main processing function (local focus) the array with a size of the maximum game entities, and another integer to keep track of how many have been added to the list.
This isn't satisfactory, as every list holds 3000+ arrays, which isn't that much, but feels like a waste, since I'll possible use the solution for 6-7 lists for varying functions.



I haven't found any C (not C++ or C#) specific solutions to achieve this. I can use pointers, but I am a bit afraid of using them (unless it's the only possible way).



The arrays do not leave the local function scope (they are to be passed to a function, then discarded), in case that changes things.



If pointers are the only solution, how can I keep track of them to avoid leaks?







c dynamic-arrays






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Aug 21 '10 at 3:23









BalkaniaBalkania

6102 gold badges7 silver badges6 bronze badges




6102 gold badges7 silver badges6 bronze badges







  • 1





    This is a (very, very small) problem in C, but how did you miss all the C++ and C# solutions for this?

    – Ignacio Vazquez-Abrams
    Aug 21 '10 at 3:28






  • 9





    "If pointers are the only solution, how can I keep track of them to avoid leaks?" Care, attention, and valgrind. This is exactly why people are so afraid if C in the first place.

    – Chris Lutz
    Aug 21 '10 at 4:00






  • 19





    You cannot use C effectively without using pointers. Don't be afraid.

    – qrdl
    Aug 21 '10 at 4:17











  • without big libs only one function for all also for structs eg: stackoverflow.com/questions/3456446/…

    – user411313
    Aug 21 '10 at 6:45






  • 3





    Using C without pointers is like using a car without fuel.

    – martinkunev
    Dec 2 '17 at 9:48












  • 1





    This is a (very, very small) problem in C, but how did you miss all the C++ and C# solutions for this?

    – Ignacio Vazquez-Abrams
    Aug 21 '10 at 3:28






  • 9





    "If pointers are the only solution, how can I keep track of them to avoid leaks?" Care, attention, and valgrind. This is exactly why people are so afraid if C in the first place.

    – Chris Lutz
    Aug 21 '10 at 4:00






  • 19





    You cannot use C effectively without using pointers. Don't be afraid.

    – qrdl
    Aug 21 '10 at 4:17











  • without big libs only one function for all also for structs eg: stackoverflow.com/questions/3456446/…

    – user411313
    Aug 21 '10 at 6:45






  • 3





    Using C without pointers is like using a car without fuel.

    – martinkunev
    Dec 2 '17 at 9:48







1




1





This is a (very, very small) problem in C, but how did you miss all the C++ and C# solutions for this?

– Ignacio Vazquez-Abrams
Aug 21 '10 at 3:28





This is a (very, very small) problem in C, but how did you miss all the C++ and C# solutions for this?

– Ignacio Vazquez-Abrams
Aug 21 '10 at 3:28




9




9





"If pointers are the only solution, how can I keep track of them to avoid leaks?" Care, attention, and valgrind. This is exactly why people are so afraid if C in the first place.

– Chris Lutz
Aug 21 '10 at 4:00





"If pointers are the only solution, how can I keep track of them to avoid leaks?" Care, attention, and valgrind. This is exactly why people are so afraid if C in the first place.

– Chris Lutz
Aug 21 '10 at 4:00




19




19





You cannot use C effectively without using pointers. Don't be afraid.

– qrdl
Aug 21 '10 at 4:17





You cannot use C effectively without using pointers. Don't be afraid.

– qrdl
Aug 21 '10 at 4:17













without big libs only one function for all also for structs eg: stackoverflow.com/questions/3456446/…

– user411313
Aug 21 '10 at 6:45





without big libs only one function for all also for structs eg: stackoverflow.com/questions/3456446/…

– user411313
Aug 21 '10 at 6:45




3




3





Using C without pointers is like using a car without fuel.

– martinkunev
Dec 2 '17 at 9:48





Using C without pointers is like using a car without fuel.

– martinkunev
Dec 2 '17 at 9:48












7 Answers
7






active

oldest

votes


















187















I can use pointers, but I am a bit afraid of using them.




If you need a dynamic array, you can't escape pointers. Why are you afraid though? They won't bite (as long as you're careful, that is). There's no built-in dynamic array in C, you'll just have to write one yourself. In C++, you can use the built-in std::vector class. C# and just about every other high-level language also have some similar class that manages dynamic arrays for you.



If you do plan to write your own, here's something to get you started: most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array. As you can see in the example below, it's not very difficult at all: (I've omitted safety checks for brevity)



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

void initArray(Array *a, size_t initialSize)
a->array = (int *)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 = (int *)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;



Using it is just as simple:



Array a;
int i;

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





share|improve this answer




















  • 1





    Thanks for the sample code. I implemented the specific function using a big array, but will implement other similar things using this, and after I get it controlled, change the others back :)

    – Balkania
    Aug 21 '10 at 11:02






  • 2





    Thanks a lot for the code. A removeArray method that gets rid of the last element would also be neat. If you allow it, I will add it to your code sample.

    – brimborium
    Jan 14 '13 at 16:15






  • 5





    %d and size_t... bit of a no-no there. If you use C99 or later, can take advantage of the addition of %z

    – Randy Howard
    Apr 28 '13 at 7:30






  • 11





    Never omit safety checks with memory allocation and reallocation.

    – Alex Reynolds
    Aug 26 '14 at 0:56






  • 2





    It's a performance tradeoff. If you double each time, then you sometimes have a 100% overhead and on average 50%. 3/2 gives you 50% worst and 25% typical. It's also close to the effective base of the Fibionacci sequence in the limit (phi) which is often praised and used for its "exponential but much less violently than base-2" characteristics, but easier to calculate. The +8 means that arrays which are reasonably small don't end up doing too many copies. It adds a multiplicative term allowing the array to quickly grow if its size is irrelevant. In specialist uses this should be tunable.

    – Dan Sheppard
    Jul 19 '16 at 20:49


















10














There are a couple of options I can think of.



  1. Linked List. You can use a linked list to make a dynamically growing array like thing. But you won't be able to do array[100] without having to walk through 1-99 first. And it might not be that handy for you to use either.

  2. Large array. Simply create an array with more than enough space for everything

  3. Resizing array. Recreate the array once you know the size and/or create a new array every time you run out of space with some margin and copy all the data to the new array.

  4. Linked List Array combination. Simply use an array with a fixed size and once you run out of space, create a new array and link to that (it would be wise to keep track of the array and the link to the next array in a struct).

It is hard to say what option would be best in your situation. Simply creating a large array is ofcourse one of the easiest solutions and shouldn't give you much problems unless it's really large.






share|improve this answer























  • How does seven arrays of 3264 integers sound for a modern-ish 2D game? If I am just being paranoid, the solution would be large array.

    – Balkania
    Aug 21 '10 at 3:34






  • 3





    Both #1 and #4 here require using pointers and dynamic memory allocation anyhow. I suggest using realloc with #3 - allocate the array a normal size, and then grow it whenever you run out. realloc will handle copying your data if necessary. As for the OP's question on memory management, you just need to malloc once at the start, free once at the end, and realloc each time you run out of room. It's not too bad.

    – Borealid
    Aug 21 '10 at 3:34






  • 1





    @Balkania: seven arrays of 3264 integers is a hair under 100KB. That's not very much memory at all.

    – Borealid
    Aug 21 '10 at 3:35






  • 1





    @Balkania: 7 * 3264 * 32 bit sounds like 91.39 kilobytes. Not that much by any standard these days ;)

    – Wolph
    Aug 21 '10 at 3:57






  • 1





    This particular omission is a shame, because it isn't entirely obvious what should happen when realloc returns NULL: a->array = (int *)realloc(a->array, a->size * sizeof(int));... Perhaps it would've been best written as: int *temp = realloc(a->array, a->size * sizeof *a->array); a->array = temp;... That way it would be obvious that whatever does happen needs to happen before the NULL value is assigned to a->array (if it is at all).

    – autistic
    Jul 11 '15 at 2:44


















8














As with everything that seems scarier at first than it was later, the best way to get over the initial fear is to immerse yourself into the discomfort of the unknown! It is at times like that which we learn the most, after all.



Unfortunately, there are limitations. While you're still learning to use a function, you shouldn't assume the role of a teacher, for example. I often read answers from those who seemingly don't know how to use realloc (i.e. the currently accepted answer!) telling others how to use it incorrectly, occasionally under the guise that they've omitted error handling, even though this is a common pitfall which needs mention. Here's an answer explaining how to use realloc correctly. Take note that the answer is storing the return value into a different variable in order to perform error checking.



Every time you call a function, and every time you use an array, you are using a pointer. The conversions are occurring implicitly, which if anything should be even scarier, as it's the things we don't see which often cause the most problems. For example, memory leaks...



Array operators are pointer operators. array[x] is really a shortcut for *(array + x), which can be broken down into: * and (array + x). It's most likely that the * is what confuses you. We can further eliminate the addition from the problem by assuming x to be 0, thus, array[0] becomes *array because adding 0 won't change the value...



... and thus we can see that *array is equivalent to array[0]. You can use one where you want to use the other, and vice versa. Array operators are pointer operators.



malloc, realloc and friends don't invent the concept of a pointer which you've been using all along; they merely use this to implement some other feature, which is a different form of storage duration, most suitable when you desire drastic, dynamic changes in size.



It is a shame that the currently accepted answer also goes against the grain of some other very well-founded advice on StackOverflow, and at the same time, misses an opportunity to introduce a little-known feature which shines for exactly this usecase: flexible array members! That's actually a pretty broken answer... :(



When you define your struct, declare your array at the end of the structure, without any upper bound. For example:



struct int_list 
size_t size;
int value[];
;


This will allow you to unite your array of int into the same allocation as your count, and having them bound like this can be very handy!



sizeof (struct int_list) will act as though value has a size of 0, so it'll tell you the size of the structure with an empty list. You still need to add to the size passed to realloc to specify the size of your list.



Another handy tip is to remember that realloc(NULL, x) is equivalent to malloc(x), and we can use this to simplify our code. For example:



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;


The reason I chose to use struct int_list ** as the first argument may not seem immediately obvious, but if you think about the second argument, any changes made to value from within push_back would not be visible to the function we're calling from, right? The same goes for the first argument, and we need to be able to modify our array, not just here but possibly also in any other function/s we pass it to...



array starts off pointing at nothing; it is an empty list. Initialising it is the same as adding to it. For example:



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



P.S. Remember to free(array); when you're done with it!






share|improve this answer

























  • "array[x] is really a shortcut for *(array + x), [...]" Are you sure about that???? See an exposition of their different behaviors: eli.thegreenplace.net/2009/10/21/….

    – C-Star-W-Star
    Jun 28 '18 at 19:30












  • Alas, @C-Star-Puppy, the one reference your resource appears to not mention at all is the C standard. That is the specification by which your compilers must adhere to legally call themselves C compilers. Your resource doesn't seem to be contradicting my information at all. Nonetheless, the standard actually has some examples such as this gem where it's revealed that array[index] is actually ptr[index] in disguise... "The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))" You can't refute the std

    – autistic
    Jun 29 '18 at 2:45











  • Try this demonstration, @C-Star-Puppy: int main(void) unsigned char lower[] = "abcdefghijklmnopqrstuvwxyz"; for (size_t x = 0; x < sizeof lower - 1; x++) putchar(x[lower]); ... You'll probably need to #include <stdio.h> and <stddef.h>... Do you see how I wrote x[lower] (with x being the integer type) rather than lower[x]? The C compiler doesn't care, because *(lower + x) is the same value as *(x + lower), and lower[x] is the former where-as x[lower] is the latter. All of these expressions are equivalent. Try them out... see for yourself, if you can't take my word...

    – autistic
    Jun 29 '18 at 2:56











  • ... and then of course there's this part, which I've placed my own emphasis into, but you really should read the entire quote without emphasis: "Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined." The same is true for functions, btw.

    – autistic
    Jun 29 '18 at 3:08











  • Ohh and on one final note, @C-Star-Puppy, Microsoft C++ is not a C compiler and hasn't been one for almost 20 years. You can enable C89 mode, suuuure, but we have evolved beyond the late 1980s in computing. For more on that topic, I suggest reading this article... and then switching to an actual C compiler such as gcc or clang for all of your C compilation, because you'll find there are so many packages that have adopted C99 features...

    – autistic
    Jun 29 '18 at 3:15


















2














When you're saying




make an array holding an index number (int) of an indeterminate number of entities




you're basically saying you're using "pointers", but one which is a array-wide local pointer instead of memory-wide pointer. Since you're conceptually already using "pointers" (i.e. id numbers that refers to an element in an array), why don't you just use regular pointers (i.e. id numbers that refers to an element in the biggest array: the whole memory).



Instead of your objects storing a resource id numbers, you can make them store a pointer instead. Basically the same thing, but much more efficient since we avoid turning "array + index" into a "pointer".



Pointers are not scary if you think of them as array index for the whole memory (which is what they actually are)






share|improve this answer






























    1














    Building on Matteo Furlans design, when he said "most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array". The difference in the "work in progress" below is that it doesn't double in size, it aims at using only what is required. I have also omitted safety checks for simplicity...Also building on brimboriums idea, I have tried to add a delete function to the code...



    The storage.h file looks like this...



    #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 */


    The storage.c file looks like this...



    #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;



    The main.c looks like this...



    #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);



    Look forward to the constructive criticism to follow...






    share|improve this answer

























    • If it is constructive criticism that you seek, better to post over at Code Review. That said, a couple of suggestions: it is imperative that code checks for success of calls to malloc() before attempting to use the allocation. In the same vein, it is a mistake to directly assign the result of realloc() to the pointer to the original memory being reallocated; if realloc() fails, NULL is returned, and code is left with a memory leak. It is much more efficient to double memory when resizing than to add 1 space at a time: fewer calls to realloc().

      – David Bowling
      Dec 9 '18 at 3:11






    • 1





      Not trying to rip anyone apart, just offering some constructive criticism, which may have been forthcoming even without your light-hearted closer ;)

      – David Bowling
      Dec 9 '18 at 3:17






    • 1





      While strict doubling may not be optimal, it is certainly better than increasing memory one byte (or one int, etc.) at a time. Doubling is a typical solution, but I don't think that there is any optimal solution that fits all circumstances. Here is why doubling is a good idea (some other factor such as 1.5 would be fine as well): if you begin with a reasonable allocation, you may not need to reallocate at all. When more memory is needed, the reasonable allocation is doubled, and so on. In this way you likely need only one or two calls to realloc().

      – David Bowling
      Dec 9 '18 at 13:58






    • 1





      For a large array, that might be one or two calls to realloc() vs. many thousands of calls to realloc(). Trim the allocation to final size with a final call to realloc(), and no excess memory is wasted.

      – David Bowling
      Dec 9 '18 at 13:59







    • 1





      I see that the result of realloc() is still being directly assigned to the original pointer. If realloc() fails, a NULL pointer is returned and would be so assigned. In this case, there would no longer be a pointer to the original memory (which has not been and can no longer be deallocated: memory leak). The right way to do this is: int *temp = realloc(/* ... */); if temp == NULL /* handle error */ else int_pointer = temp; . Also, no need to cast malloc() and friends. Consider int_pointer = malloc(sizeof *int_pointer);: idiomatic, less error-prone, maintainable.

      – David Bowling
      Dec 9 '18 at 14:18


















    0














    To create an array of unlimited items of any sort of type:



    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);



    and how to use it:



    // 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;



    This vector/array can hold any type of item and it is completely dynamic in size.






    share|improve this answer






























      0














      Well, I guess if you need to remove an element you will make a copy of the array despising the element to be excluded.



      // 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);
      //


      Assume that getElement2BRemove(), copy2TempVector( void* ...) and fillFromTempVector(...) are auxiliary methods to handle the temp vector.






      share|improve this answer

























      • It's unclear if this is actually an answer to the question posed, or if it a comment.

        – user1531971
        Nov 27 '18 at 18:43











      • It's an opinion for "how to" and I am asking for confirmation (Am I wrong?) IF someone has a better idea. ;)

        – JOSMAR BARBOSA - M4NOV3Y
        Nov 27 '18 at 18:59











      • I guess I don't understand your last sentence. Since SO is not a threaded forum, open questions like this in answers look odd.

        – user1531971
        Nov 27 '18 at 19:02











      • ok, now its an assertion. ...philosophers... ;)

        – JOSMAR BARBOSA - M4NOV3Y
        Nov 27 '18 at 19:55






      • 1





        I fixed up your last sentence to what I think you want to say.

        – user1531971
        Nov 27 '18 at 19:58













      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3536153%2fc-dynamically-growing-array%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      7 Answers
      7






      active

      oldest

      votes








      7 Answers
      7






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      187















      I can use pointers, but I am a bit afraid of using them.




      If you need a dynamic array, you can't escape pointers. Why are you afraid though? They won't bite (as long as you're careful, that is). There's no built-in dynamic array in C, you'll just have to write one yourself. In C++, you can use the built-in std::vector class. C# and just about every other high-level language also have some similar class that manages dynamic arrays for you.



      If you do plan to write your own, here's something to get you started: most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array. As you can see in the example below, it's not very difficult at all: (I've omitted safety checks for brevity)



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

      void initArray(Array *a, size_t initialSize)
      a->array = (int *)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 = (int *)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;



      Using it is just as simple:



      Array a;
      int i;

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





      share|improve this answer




















      • 1





        Thanks for the sample code. I implemented the specific function using a big array, but will implement other similar things using this, and after I get it controlled, change the others back :)

        – Balkania
        Aug 21 '10 at 11:02






      • 2





        Thanks a lot for the code. A removeArray method that gets rid of the last element would also be neat. If you allow it, I will add it to your code sample.

        – brimborium
        Jan 14 '13 at 16:15






      • 5





        %d and size_t... bit of a no-no there. If you use C99 or later, can take advantage of the addition of %z

        – Randy Howard
        Apr 28 '13 at 7:30






      • 11





        Never omit safety checks with memory allocation and reallocation.

        – Alex Reynolds
        Aug 26 '14 at 0:56






      • 2





        It's a performance tradeoff. If you double each time, then you sometimes have a 100% overhead and on average 50%. 3/2 gives you 50% worst and 25% typical. It's also close to the effective base of the Fibionacci sequence in the limit (phi) which is often praised and used for its "exponential but much less violently than base-2" characteristics, but easier to calculate. The +8 means that arrays which are reasonably small don't end up doing too many copies. It adds a multiplicative term allowing the array to quickly grow if its size is irrelevant. In specialist uses this should be tunable.

        – Dan Sheppard
        Jul 19 '16 at 20:49















      187















      I can use pointers, but I am a bit afraid of using them.




      If you need a dynamic array, you can't escape pointers. Why are you afraid though? They won't bite (as long as you're careful, that is). There's no built-in dynamic array in C, you'll just have to write one yourself. In C++, you can use the built-in std::vector class. C# and just about every other high-level language also have some similar class that manages dynamic arrays for you.



      If you do plan to write your own, here's something to get you started: most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array. As you can see in the example below, it's not very difficult at all: (I've omitted safety checks for brevity)



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

      void initArray(Array *a, size_t initialSize)
      a->array = (int *)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 = (int *)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;



      Using it is just as simple:



      Array a;
      int i;

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





      share|improve this answer




















      • 1





        Thanks for the sample code. I implemented the specific function using a big array, but will implement other similar things using this, and after I get it controlled, change the others back :)

        – Balkania
        Aug 21 '10 at 11:02






      • 2





        Thanks a lot for the code. A removeArray method that gets rid of the last element would also be neat. If you allow it, I will add it to your code sample.

        – brimborium
        Jan 14 '13 at 16:15






      • 5





        %d and size_t... bit of a no-no there. If you use C99 or later, can take advantage of the addition of %z

        – Randy Howard
        Apr 28 '13 at 7:30






      • 11





        Never omit safety checks with memory allocation and reallocation.

        – Alex Reynolds
        Aug 26 '14 at 0:56






      • 2





        It's a performance tradeoff. If you double each time, then you sometimes have a 100% overhead and on average 50%. 3/2 gives you 50% worst and 25% typical. It's also close to the effective base of the Fibionacci sequence in the limit (phi) which is often praised and used for its "exponential but much less violently than base-2" characteristics, but easier to calculate. The +8 means that arrays which are reasonably small don't end up doing too many copies. It adds a multiplicative term allowing the array to quickly grow if its size is irrelevant. In specialist uses this should be tunable.

        – Dan Sheppard
        Jul 19 '16 at 20:49













      187












      187








      187








      I can use pointers, but I am a bit afraid of using them.




      If you need a dynamic array, you can't escape pointers. Why are you afraid though? They won't bite (as long as you're careful, that is). There's no built-in dynamic array in C, you'll just have to write one yourself. In C++, you can use the built-in std::vector class. C# and just about every other high-level language also have some similar class that manages dynamic arrays for you.



      If you do plan to write your own, here's something to get you started: most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array. As you can see in the example below, it's not very difficult at all: (I've omitted safety checks for brevity)



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

      void initArray(Array *a, size_t initialSize)
      a->array = (int *)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 = (int *)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;



      Using it is just as simple:



      Array a;
      int i;

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





      share|improve this answer
















      I can use pointers, but I am a bit afraid of using them.




      If you need a dynamic array, you can't escape pointers. Why are you afraid though? They won't bite (as long as you're careful, that is). There's no built-in dynamic array in C, you'll just have to write one yourself. In C++, you can use the built-in std::vector class. C# and just about every other high-level language also have some similar class that manages dynamic arrays for you.



      If you do plan to write your own, here's something to get you started: most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array. As you can see in the example below, it's not very difficult at all: (I've omitted safety checks for brevity)



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

      void initArray(Array *a, size_t initialSize)
      a->array = (int *)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 = (int *)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;



      Using it is just as simple:



      Array a;
      int i;

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






      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Jan 4 '17 at 15:39









      Matteo Furlan

      95 bronze badges




      95 bronze badges










      answered Aug 21 '10 at 4:01









      casablancacasablanca

      61k5 gold badges111 silver badges140 bronze badges




      61k5 gold badges111 silver badges140 bronze badges







      • 1





        Thanks for the sample code. I implemented the specific function using a big array, but will implement other similar things using this, and after I get it controlled, change the others back :)

        – Balkania
        Aug 21 '10 at 11:02






      • 2





        Thanks a lot for the code. A removeArray method that gets rid of the last element would also be neat. If you allow it, I will add it to your code sample.

        – brimborium
        Jan 14 '13 at 16:15






      • 5





        %d and size_t... bit of a no-no there. If you use C99 or later, can take advantage of the addition of %z

        – Randy Howard
        Apr 28 '13 at 7:30






      • 11





        Never omit safety checks with memory allocation and reallocation.

        – Alex Reynolds
        Aug 26 '14 at 0:56






      • 2





        It's a performance tradeoff. If you double each time, then you sometimes have a 100% overhead and on average 50%. 3/2 gives you 50% worst and 25% typical. It's also close to the effective base of the Fibionacci sequence in the limit (phi) which is often praised and used for its "exponential but much less violently than base-2" characteristics, but easier to calculate. The +8 means that arrays which are reasonably small don't end up doing too many copies. It adds a multiplicative term allowing the array to quickly grow if its size is irrelevant. In specialist uses this should be tunable.

        – Dan Sheppard
        Jul 19 '16 at 20:49












      • 1





        Thanks for the sample code. I implemented the specific function using a big array, but will implement other similar things using this, and after I get it controlled, change the others back :)

        – Balkania
        Aug 21 '10 at 11:02






      • 2





        Thanks a lot for the code. A removeArray method that gets rid of the last element would also be neat. If you allow it, I will add it to your code sample.

        – brimborium
        Jan 14 '13 at 16:15






      • 5





        %d and size_t... bit of a no-no there. If you use C99 or later, can take advantage of the addition of %z

        – Randy Howard
        Apr 28 '13 at 7:30






      • 11





        Never omit safety checks with memory allocation and reallocation.

        – Alex Reynolds
        Aug 26 '14 at 0:56






      • 2





        It's a performance tradeoff. If you double each time, then you sometimes have a 100% overhead and on average 50%. 3/2 gives you 50% worst and 25% typical. It's also close to the effective base of the Fibionacci sequence in the limit (phi) which is often praised and used for its "exponential but much less violently than base-2" characteristics, but easier to calculate. The +8 means that arrays which are reasonably small don't end up doing too many copies. It adds a multiplicative term allowing the array to quickly grow if its size is irrelevant. In specialist uses this should be tunable.

        – Dan Sheppard
        Jul 19 '16 at 20:49







      1




      1





      Thanks for the sample code. I implemented the specific function using a big array, but will implement other similar things using this, and after I get it controlled, change the others back :)

      – Balkania
      Aug 21 '10 at 11:02





      Thanks for the sample code. I implemented the specific function using a big array, but will implement other similar things using this, and after I get it controlled, change the others back :)

      – Balkania
      Aug 21 '10 at 11:02




      2




      2





      Thanks a lot for the code. A removeArray method that gets rid of the last element would also be neat. If you allow it, I will add it to your code sample.

      – brimborium
      Jan 14 '13 at 16:15





      Thanks a lot for the code. A removeArray method that gets rid of the last element would also be neat. If you allow it, I will add it to your code sample.

      – brimborium
      Jan 14 '13 at 16:15




      5




      5





      %d and size_t... bit of a no-no there. If you use C99 or later, can take advantage of the addition of %z

      – Randy Howard
      Apr 28 '13 at 7:30





      %d and size_t... bit of a no-no there. If you use C99 or later, can take advantage of the addition of %z

      – Randy Howard
      Apr 28 '13 at 7:30




      11




      11





      Never omit safety checks with memory allocation and reallocation.

      – Alex Reynolds
      Aug 26 '14 at 0:56





      Never omit safety checks with memory allocation and reallocation.

      – Alex Reynolds
      Aug 26 '14 at 0:56




      2




      2





      It's a performance tradeoff. If you double each time, then you sometimes have a 100% overhead and on average 50%. 3/2 gives you 50% worst and 25% typical. It's also close to the effective base of the Fibionacci sequence in the limit (phi) which is often praised and used for its "exponential but much less violently than base-2" characteristics, but easier to calculate. The +8 means that arrays which are reasonably small don't end up doing too many copies. It adds a multiplicative term allowing the array to quickly grow if its size is irrelevant. In specialist uses this should be tunable.

      – Dan Sheppard
      Jul 19 '16 at 20:49





      It's a performance tradeoff. If you double each time, then you sometimes have a 100% overhead and on average 50%. 3/2 gives you 50% worst and 25% typical. It's also close to the effective base of the Fibionacci sequence in the limit (phi) which is often praised and used for its "exponential but much less violently than base-2" characteristics, but easier to calculate. The +8 means that arrays which are reasonably small don't end up doing too many copies. It adds a multiplicative term allowing the array to quickly grow if its size is irrelevant. In specialist uses this should be tunable.

      – Dan Sheppard
      Jul 19 '16 at 20:49













      10














      There are a couple of options I can think of.



      1. Linked List. You can use a linked list to make a dynamically growing array like thing. But you won't be able to do array[100] without having to walk through 1-99 first. And it might not be that handy for you to use either.

      2. Large array. Simply create an array with more than enough space for everything

      3. Resizing array. Recreate the array once you know the size and/or create a new array every time you run out of space with some margin and copy all the data to the new array.

      4. Linked List Array combination. Simply use an array with a fixed size and once you run out of space, create a new array and link to that (it would be wise to keep track of the array and the link to the next array in a struct).

      It is hard to say what option would be best in your situation. Simply creating a large array is ofcourse one of the easiest solutions and shouldn't give you much problems unless it's really large.






      share|improve this answer























      • How does seven arrays of 3264 integers sound for a modern-ish 2D game? If I am just being paranoid, the solution would be large array.

        – Balkania
        Aug 21 '10 at 3:34






      • 3





        Both #1 and #4 here require using pointers and dynamic memory allocation anyhow. I suggest using realloc with #3 - allocate the array a normal size, and then grow it whenever you run out. realloc will handle copying your data if necessary. As for the OP's question on memory management, you just need to malloc once at the start, free once at the end, and realloc each time you run out of room. It's not too bad.

        – Borealid
        Aug 21 '10 at 3:34






      • 1





        @Balkania: seven arrays of 3264 integers is a hair under 100KB. That's not very much memory at all.

        – Borealid
        Aug 21 '10 at 3:35






      • 1





        @Balkania: 7 * 3264 * 32 bit sounds like 91.39 kilobytes. Not that much by any standard these days ;)

        – Wolph
        Aug 21 '10 at 3:57






      • 1





        This particular omission is a shame, because it isn't entirely obvious what should happen when realloc returns NULL: a->array = (int *)realloc(a->array, a->size * sizeof(int));... Perhaps it would've been best written as: int *temp = realloc(a->array, a->size * sizeof *a->array); a->array = temp;... That way it would be obvious that whatever does happen needs to happen before the NULL value is assigned to a->array (if it is at all).

        – autistic
        Jul 11 '15 at 2:44















      10














      There are a couple of options I can think of.



      1. Linked List. You can use a linked list to make a dynamically growing array like thing. But you won't be able to do array[100] without having to walk through 1-99 first. And it might not be that handy for you to use either.

      2. Large array. Simply create an array with more than enough space for everything

      3. Resizing array. Recreate the array once you know the size and/or create a new array every time you run out of space with some margin and copy all the data to the new array.

      4. Linked List Array combination. Simply use an array with a fixed size and once you run out of space, create a new array and link to that (it would be wise to keep track of the array and the link to the next array in a struct).

      It is hard to say what option would be best in your situation. Simply creating a large array is ofcourse one of the easiest solutions and shouldn't give you much problems unless it's really large.






      share|improve this answer























      • How does seven arrays of 3264 integers sound for a modern-ish 2D game? If I am just being paranoid, the solution would be large array.

        – Balkania
        Aug 21 '10 at 3:34






      • 3





        Both #1 and #4 here require using pointers and dynamic memory allocation anyhow. I suggest using realloc with #3 - allocate the array a normal size, and then grow it whenever you run out. realloc will handle copying your data if necessary. As for the OP's question on memory management, you just need to malloc once at the start, free once at the end, and realloc each time you run out of room. It's not too bad.

        – Borealid
        Aug 21 '10 at 3:34






      • 1





        @Balkania: seven arrays of 3264 integers is a hair under 100KB. That's not very much memory at all.

        – Borealid
        Aug 21 '10 at 3:35






      • 1





        @Balkania: 7 * 3264 * 32 bit sounds like 91.39 kilobytes. Not that much by any standard these days ;)

        – Wolph
        Aug 21 '10 at 3:57






      • 1





        This particular omission is a shame, because it isn't entirely obvious what should happen when realloc returns NULL: a->array = (int *)realloc(a->array, a->size * sizeof(int));... Perhaps it would've been best written as: int *temp = realloc(a->array, a->size * sizeof *a->array); a->array = temp;... That way it would be obvious that whatever does happen needs to happen before the NULL value is assigned to a->array (if it is at all).

        – autistic
        Jul 11 '15 at 2:44













      10












      10








      10







      There are a couple of options I can think of.



      1. Linked List. You can use a linked list to make a dynamically growing array like thing. But you won't be able to do array[100] without having to walk through 1-99 first. And it might not be that handy for you to use either.

      2. Large array. Simply create an array with more than enough space for everything

      3. Resizing array. Recreate the array once you know the size and/or create a new array every time you run out of space with some margin and copy all the data to the new array.

      4. Linked List Array combination. Simply use an array with a fixed size and once you run out of space, create a new array and link to that (it would be wise to keep track of the array and the link to the next array in a struct).

      It is hard to say what option would be best in your situation. Simply creating a large array is ofcourse one of the easiest solutions and shouldn't give you much problems unless it's really large.






      share|improve this answer













      There are a couple of options I can think of.



      1. Linked List. You can use a linked list to make a dynamically growing array like thing. But you won't be able to do array[100] without having to walk through 1-99 first. And it might not be that handy for you to use either.

      2. Large array. Simply create an array with more than enough space for everything

      3. Resizing array. Recreate the array once you know the size and/or create a new array every time you run out of space with some margin and copy all the data to the new array.

      4. Linked List Array combination. Simply use an array with a fixed size and once you run out of space, create a new array and link to that (it would be wise to keep track of the array and the link to the next array in a struct).

      It is hard to say what option would be best in your situation. Simply creating a large array is ofcourse one of the easiest solutions and shouldn't give you much problems unless it's really large.







      share|improve this answer












      share|improve this answer



      share|improve this answer










      answered Aug 21 '10 at 3:31









      WolphWolph

      59k8 gold badges107 silver badges134 bronze badges




      59k8 gold badges107 silver badges134 bronze badges












      • How does seven arrays of 3264 integers sound for a modern-ish 2D game? If I am just being paranoid, the solution would be large array.

        – Balkania
        Aug 21 '10 at 3:34






      • 3





        Both #1 and #4 here require using pointers and dynamic memory allocation anyhow. I suggest using realloc with #3 - allocate the array a normal size, and then grow it whenever you run out. realloc will handle copying your data if necessary. As for the OP's question on memory management, you just need to malloc once at the start, free once at the end, and realloc each time you run out of room. It's not too bad.

        – Borealid
        Aug 21 '10 at 3:34






      • 1





        @Balkania: seven arrays of 3264 integers is a hair under 100KB. That's not very much memory at all.

        – Borealid
        Aug 21 '10 at 3:35






      • 1





        @Balkania: 7 * 3264 * 32 bit sounds like 91.39 kilobytes. Not that much by any standard these days ;)

        – Wolph
        Aug 21 '10 at 3:57






      • 1





        This particular omission is a shame, because it isn't entirely obvious what should happen when realloc returns NULL: a->array = (int *)realloc(a->array, a->size * sizeof(int));... Perhaps it would've been best written as: int *temp = realloc(a->array, a->size * sizeof *a->array); a->array = temp;... That way it would be obvious that whatever does happen needs to happen before the NULL value is assigned to a->array (if it is at all).

        – autistic
        Jul 11 '15 at 2:44

















      • How does seven arrays of 3264 integers sound for a modern-ish 2D game? If I am just being paranoid, the solution would be large array.

        – Balkania
        Aug 21 '10 at 3:34






      • 3





        Both #1 and #4 here require using pointers and dynamic memory allocation anyhow. I suggest using realloc with #3 - allocate the array a normal size, and then grow it whenever you run out. realloc will handle copying your data if necessary. As for the OP's question on memory management, you just need to malloc once at the start, free once at the end, and realloc each time you run out of room. It's not too bad.

        – Borealid
        Aug 21 '10 at 3:34






      • 1





        @Balkania: seven arrays of 3264 integers is a hair under 100KB. That's not very much memory at all.

        – Borealid
        Aug 21 '10 at 3:35






      • 1





        @Balkania: 7 * 3264 * 32 bit sounds like 91.39 kilobytes. Not that much by any standard these days ;)

        – Wolph
        Aug 21 '10 at 3:57






      • 1





        This particular omission is a shame, because it isn't entirely obvious what should happen when realloc returns NULL: a->array = (int *)realloc(a->array, a->size * sizeof(int));... Perhaps it would've been best written as: int *temp = realloc(a->array, a->size * sizeof *a->array); a->array = temp;... That way it would be obvious that whatever does happen needs to happen before the NULL value is assigned to a->array (if it is at all).

        – autistic
        Jul 11 '15 at 2:44
















      How does seven arrays of 3264 integers sound for a modern-ish 2D game? If I am just being paranoid, the solution would be large array.

      – Balkania
      Aug 21 '10 at 3:34





      How does seven arrays of 3264 integers sound for a modern-ish 2D game? If I am just being paranoid, the solution would be large array.

      – Balkania
      Aug 21 '10 at 3:34




      3




      3





      Both #1 and #4 here require using pointers and dynamic memory allocation anyhow. I suggest using realloc with #3 - allocate the array a normal size, and then grow it whenever you run out. realloc will handle copying your data if necessary. As for the OP's question on memory management, you just need to malloc once at the start, free once at the end, and realloc each time you run out of room. It's not too bad.

      – Borealid
      Aug 21 '10 at 3:34





      Both #1 and #4 here require using pointers and dynamic memory allocation anyhow. I suggest using realloc with #3 - allocate the array a normal size, and then grow it whenever you run out. realloc will handle copying your data if necessary. As for the OP's question on memory management, you just need to malloc once at the start, free once at the end, and realloc each time you run out of room. It's not too bad.

      – Borealid
      Aug 21 '10 at 3:34




      1




      1





      @Balkania: seven arrays of 3264 integers is a hair under 100KB. That's not very much memory at all.

      – Borealid
      Aug 21 '10 at 3:35





      @Balkania: seven arrays of 3264 integers is a hair under 100KB. That's not very much memory at all.

      – Borealid
      Aug 21 '10 at 3:35




      1




      1





      @Balkania: 7 * 3264 * 32 bit sounds like 91.39 kilobytes. Not that much by any standard these days ;)

      – Wolph
      Aug 21 '10 at 3:57





      @Balkania: 7 * 3264 * 32 bit sounds like 91.39 kilobytes. Not that much by any standard these days ;)

      – Wolph
      Aug 21 '10 at 3:57




      1




      1





      This particular omission is a shame, because it isn't entirely obvious what should happen when realloc returns NULL: a->array = (int *)realloc(a->array, a->size * sizeof(int));... Perhaps it would've been best written as: int *temp = realloc(a->array, a->size * sizeof *a->array); a->array = temp;... That way it would be obvious that whatever does happen needs to happen before the NULL value is assigned to a->array (if it is at all).

      – autistic
      Jul 11 '15 at 2:44





      This particular omission is a shame, because it isn't entirely obvious what should happen when realloc returns NULL: a->array = (int *)realloc(a->array, a->size * sizeof(int));... Perhaps it would've been best written as: int *temp = realloc(a->array, a->size * sizeof *a->array); a->array = temp;... That way it would be obvious that whatever does happen needs to happen before the NULL value is assigned to a->array (if it is at all).

      – autistic
      Jul 11 '15 at 2:44











      8














      As with everything that seems scarier at first than it was later, the best way to get over the initial fear is to immerse yourself into the discomfort of the unknown! It is at times like that which we learn the most, after all.



      Unfortunately, there are limitations. While you're still learning to use a function, you shouldn't assume the role of a teacher, for example. I often read answers from those who seemingly don't know how to use realloc (i.e. the currently accepted answer!) telling others how to use it incorrectly, occasionally under the guise that they've omitted error handling, even though this is a common pitfall which needs mention. Here's an answer explaining how to use realloc correctly. Take note that the answer is storing the return value into a different variable in order to perform error checking.



      Every time you call a function, and every time you use an array, you are using a pointer. The conversions are occurring implicitly, which if anything should be even scarier, as it's the things we don't see which often cause the most problems. For example, memory leaks...



      Array operators are pointer operators. array[x] is really a shortcut for *(array + x), which can be broken down into: * and (array + x). It's most likely that the * is what confuses you. We can further eliminate the addition from the problem by assuming x to be 0, thus, array[0] becomes *array because adding 0 won't change the value...



      ... and thus we can see that *array is equivalent to array[0]. You can use one where you want to use the other, and vice versa. Array operators are pointer operators.



      malloc, realloc and friends don't invent the concept of a pointer which you've been using all along; they merely use this to implement some other feature, which is a different form of storage duration, most suitable when you desire drastic, dynamic changes in size.



      It is a shame that the currently accepted answer also goes against the grain of some other very well-founded advice on StackOverflow, and at the same time, misses an opportunity to introduce a little-known feature which shines for exactly this usecase: flexible array members! That's actually a pretty broken answer... :(



      When you define your struct, declare your array at the end of the structure, without any upper bound. For example:



      struct int_list 
      size_t size;
      int value[];
      ;


      This will allow you to unite your array of int into the same allocation as your count, and having them bound like this can be very handy!



      sizeof (struct int_list) will act as though value has a size of 0, so it'll tell you the size of the structure with an empty list. You still need to add to the size passed to realloc to specify the size of your list.



      Another handy tip is to remember that realloc(NULL, x) is equivalent to malloc(x), and we can use this to simplify our code. For example:



      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;


      The reason I chose to use struct int_list ** as the first argument may not seem immediately obvious, but if you think about the second argument, any changes made to value from within push_back would not be visible to the function we're calling from, right? The same goes for the first argument, and we need to be able to modify our array, not just here but possibly also in any other function/s we pass it to...



      array starts off pointing at nothing; it is an empty list. Initialising it is the same as adding to it. For example:



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



      P.S. Remember to free(array); when you're done with it!






      share|improve this answer

























      • "array[x] is really a shortcut for *(array + x), [...]" Are you sure about that???? See an exposition of their different behaviors: eli.thegreenplace.net/2009/10/21/….

        – C-Star-W-Star
        Jun 28 '18 at 19:30












      • Alas, @C-Star-Puppy, the one reference your resource appears to not mention at all is the C standard. That is the specification by which your compilers must adhere to legally call themselves C compilers. Your resource doesn't seem to be contradicting my information at all. Nonetheless, the standard actually has some examples such as this gem where it's revealed that array[index] is actually ptr[index] in disguise... "The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))" You can't refute the std

        – autistic
        Jun 29 '18 at 2:45











      • Try this demonstration, @C-Star-Puppy: int main(void) unsigned char lower[] = "abcdefghijklmnopqrstuvwxyz"; for (size_t x = 0; x < sizeof lower - 1; x++) putchar(x[lower]); ... You'll probably need to #include <stdio.h> and <stddef.h>... Do you see how I wrote x[lower] (with x being the integer type) rather than lower[x]? The C compiler doesn't care, because *(lower + x) is the same value as *(x + lower), and lower[x] is the former where-as x[lower] is the latter. All of these expressions are equivalent. Try them out... see for yourself, if you can't take my word...

        – autistic
        Jun 29 '18 at 2:56











      • ... and then of course there's this part, which I've placed my own emphasis into, but you really should read the entire quote without emphasis: "Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined." The same is true for functions, btw.

        – autistic
        Jun 29 '18 at 3:08











      • Ohh and on one final note, @C-Star-Puppy, Microsoft C++ is not a C compiler and hasn't been one for almost 20 years. You can enable C89 mode, suuuure, but we have evolved beyond the late 1980s in computing. For more on that topic, I suggest reading this article... and then switching to an actual C compiler such as gcc or clang for all of your C compilation, because you'll find there are so many packages that have adopted C99 features...

        – autistic
        Jun 29 '18 at 3:15















      8














      As with everything that seems scarier at first than it was later, the best way to get over the initial fear is to immerse yourself into the discomfort of the unknown! It is at times like that which we learn the most, after all.



      Unfortunately, there are limitations. While you're still learning to use a function, you shouldn't assume the role of a teacher, for example. I often read answers from those who seemingly don't know how to use realloc (i.e. the currently accepted answer!) telling others how to use it incorrectly, occasionally under the guise that they've omitted error handling, even though this is a common pitfall which needs mention. Here's an answer explaining how to use realloc correctly. Take note that the answer is storing the return value into a different variable in order to perform error checking.



      Every time you call a function, and every time you use an array, you are using a pointer. The conversions are occurring implicitly, which if anything should be even scarier, as it's the things we don't see which often cause the most problems. For example, memory leaks...



      Array operators are pointer operators. array[x] is really a shortcut for *(array + x), which can be broken down into: * and (array + x). It's most likely that the * is what confuses you. We can further eliminate the addition from the problem by assuming x to be 0, thus, array[0] becomes *array because adding 0 won't change the value...



      ... and thus we can see that *array is equivalent to array[0]. You can use one where you want to use the other, and vice versa. Array operators are pointer operators.



      malloc, realloc and friends don't invent the concept of a pointer which you've been using all along; they merely use this to implement some other feature, which is a different form of storage duration, most suitable when you desire drastic, dynamic changes in size.



      It is a shame that the currently accepted answer also goes against the grain of some other very well-founded advice on StackOverflow, and at the same time, misses an opportunity to introduce a little-known feature which shines for exactly this usecase: flexible array members! That's actually a pretty broken answer... :(



      When you define your struct, declare your array at the end of the structure, without any upper bound. For example:



      struct int_list 
      size_t size;
      int value[];
      ;


      This will allow you to unite your array of int into the same allocation as your count, and having them bound like this can be very handy!



      sizeof (struct int_list) will act as though value has a size of 0, so it'll tell you the size of the structure with an empty list. You still need to add to the size passed to realloc to specify the size of your list.



      Another handy tip is to remember that realloc(NULL, x) is equivalent to malloc(x), and we can use this to simplify our code. For example:



      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;


      The reason I chose to use struct int_list ** as the first argument may not seem immediately obvious, but if you think about the second argument, any changes made to value from within push_back would not be visible to the function we're calling from, right? The same goes for the first argument, and we need to be able to modify our array, not just here but possibly also in any other function/s we pass it to...



      array starts off pointing at nothing; it is an empty list. Initialising it is the same as adding to it. For example:



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



      P.S. Remember to free(array); when you're done with it!






      share|improve this answer

























      • "array[x] is really a shortcut for *(array + x), [...]" Are you sure about that???? See an exposition of their different behaviors: eli.thegreenplace.net/2009/10/21/….

        – C-Star-W-Star
        Jun 28 '18 at 19:30












      • Alas, @C-Star-Puppy, the one reference your resource appears to not mention at all is the C standard. That is the specification by which your compilers must adhere to legally call themselves C compilers. Your resource doesn't seem to be contradicting my information at all. Nonetheless, the standard actually has some examples such as this gem where it's revealed that array[index] is actually ptr[index] in disguise... "The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))" You can't refute the std

        – autistic
        Jun 29 '18 at 2:45











      • Try this demonstration, @C-Star-Puppy: int main(void) unsigned char lower[] = "abcdefghijklmnopqrstuvwxyz"; for (size_t x = 0; x < sizeof lower - 1; x++) putchar(x[lower]); ... You'll probably need to #include <stdio.h> and <stddef.h>... Do you see how I wrote x[lower] (with x being the integer type) rather than lower[x]? The C compiler doesn't care, because *(lower + x) is the same value as *(x + lower), and lower[x] is the former where-as x[lower] is the latter. All of these expressions are equivalent. Try them out... see for yourself, if you can't take my word...

        – autistic
        Jun 29 '18 at 2:56











      • ... and then of course there's this part, which I've placed my own emphasis into, but you really should read the entire quote without emphasis: "Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined." The same is true for functions, btw.

        – autistic
        Jun 29 '18 at 3:08











      • Ohh and on one final note, @C-Star-Puppy, Microsoft C++ is not a C compiler and hasn't been one for almost 20 years. You can enable C89 mode, suuuure, but we have evolved beyond the late 1980s in computing. For more on that topic, I suggest reading this article... and then switching to an actual C compiler such as gcc or clang for all of your C compilation, because you'll find there are so many packages that have adopted C99 features...

        – autistic
        Jun 29 '18 at 3:15













      8












      8








      8







      As with everything that seems scarier at first than it was later, the best way to get over the initial fear is to immerse yourself into the discomfort of the unknown! It is at times like that which we learn the most, after all.



      Unfortunately, there are limitations. While you're still learning to use a function, you shouldn't assume the role of a teacher, for example. I often read answers from those who seemingly don't know how to use realloc (i.e. the currently accepted answer!) telling others how to use it incorrectly, occasionally under the guise that they've omitted error handling, even though this is a common pitfall which needs mention. Here's an answer explaining how to use realloc correctly. Take note that the answer is storing the return value into a different variable in order to perform error checking.



      Every time you call a function, and every time you use an array, you are using a pointer. The conversions are occurring implicitly, which if anything should be even scarier, as it's the things we don't see which often cause the most problems. For example, memory leaks...



      Array operators are pointer operators. array[x] is really a shortcut for *(array + x), which can be broken down into: * and (array + x). It's most likely that the * is what confuses you. We can further eliminate the addition from the problem by assuming x to be 0, thus, array[0] becomes *array because adding 0 won't change the value...



      ... and thus we can see that *array is equivalent to array[0]. You can use one where you want to use the other, and vice versa. Array operators are pointer operators.



      malloc, realloc and friends don't invent the concept of a pointer which you've been using all along; they merely use this to implement some other feature, which is a different form of storage duration, most suitable when you desire drastic, dynamic changes in size.



      It is a shame that the currently accepted answer also goes against the grain of some other very well-founded advice on StackOverflow, and at the same time, misses an opportunity to introduce a little-known feature which shines for exactly this usecase: flexible array members! That's actually a pretty broken answer... :(



      When you define your struct, declare your array at the end of the structure, without any upper bound. For example:



      struct int_list 
      size_t size;
      int value[];
      ;


      This will allow you to unite your array of int into the same allocation as your count, and having them bound like this can be very handy!



      sizeof (struct int_list) will act as though value has a size of 0, so it'll tell you the size of the structure with an empty list. You still need to add to the size passed to realloc to specify the size of your list.



      Another handy tip is to remember that realloc(NULL, x) is equivalent to malloc(x), and we can use this to simplify our code. For example:



      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;


      The reason I chose to use struct int_list ** as the first argument may not seem immediately obvious, but if you think about the second argument, any changes made to value from within push_back would not be visible to the function we're calling from, right? The same goes for the first argument, and we need to be able to modify our array, not just here but possibly also in any other function/s we pass it to...



      array starts off pointing at nothing; it is an empty list. Initialising it is the same as adding to it. For example:



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



      P.S. Remember to free(array); when you're done with it!






      share|improve this answer















      As with everything that seems scarier at first than it was later, the best way to get over the initial fear is to immerse yourself into the discomfort of the unknown! It is at times like that which we learn the most, after all.



      Unfortunately, there are limitations. While you're still learning to use a function, you shouldn't assume the role of a teacher, for example. I often read answers from those who seemingly don't know how to use realloc (i.e. the currently accepted answer!) telling others how to use it incorrectly, occasionally under the guise that they've omitted error handling, even though this is a common pitfall which needs mention. Here's an answer explaining how to use realloc correctly. Take note that the answer is storing the return value into a different variable in order to perform error checking.



      Every time you call a function, and every time you use an array, you are using a pointer. The conversions are occurring implicitly, which if anything should be even scarier, as it's the things we don't see which often cause the most problems. For example, memory leaks...



      Array operators are pointer operators. array[x] is really a shortcut for *(array + x), which can be broken down into: * and (array + x). It's most likely that the * is what confuses you. We can further eliminate the addition from the problem by assuming x to be 0, thus, array[0] becomes *array because adding 0 won't change the value...



      ... and thus we can see that *array is equivalent to array[0]. You can use one where you want to use the other, and vice versa. Array operators are pointer operators.



      malloc, realloc and friends don't invent the concept of a pointer which you've been using all along; they merely use this to implement some other feature, which is a different form of storage duration, most suitable when you desire drastic, dynamic changes in size.



      It is a shame that the currently accepted answer also goes against the grain of some other very well-founded advice on StackOverflow, and at the same time, misses an opportunity to introduce a little-known feature which shines for exactly this usecase: flexible array members! That's actually a pretty broken answer... :(



      When you define your struct, declare your array at the end of the structure, without any upper bound. For example:



      struct int_list 
      size_t size;
      int value[];
      ;


      This will allow you to unite your array of int into the same allocation as your count, and having them bound like this can be very handy!



      sizeof (struct int_list) will act as though value has a size of 0, so it'll tell you the size of the structure with an empty list. You still need to add to the size passed to realloc to specify the size of your list.



      Another handy tip is to remember that realloc(NULL, x) is equivalent to malloc(x), and we can use this to simplify our code. For example:



      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;


      The reason I chose to use struct int_list ** as the first argument may not seem immediately obvious, but if you think about the second argument, any changes made to value from within push_back would not be visible to the function we're calling from, right? The same goes for the first argument, and we need to be able to modify our array, not just here but possibly also in any other function/s we pass it to...



      array starts off pointing at nothing; it is an empty list. Initialising it is the same as adding to it. For example:



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



      P.S. Remember to free(array); when you're done with it!







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Aug 7 '18 at 14:31

























      answered Sep 21 '17 at 19:37









      autisticautistic

      1




      1












      • "array[x] is really a shortcut for *(array + x), [...]" Are you sure about that???? See an exposition of their different behaviors: eli.thegreenplace.net/2009/10/21/….

        – C-Star-W-Star
        Jun 28 '18 at 19:30












      • Alas, @C-Star-Puppy, the one reference your resource appears to not mention at all is the C standard. That is the specification by which your compilers must adhere to legally call themselves C compilers. Your resource doesn't seem to be contradicting my information at all. Nonetheless, the standard actually has some examples such as this gem where it's revealed that array[index] is actually ptr[index] in disguise... "The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))" You can't refute the std

        – autistic
        Jun 29 '18 at 2:45











      • Try this demonstration, @C-Star-Puppy: int main(void) unsigned char lower[] = "abcdefghijklmnopqrstuvwxyz"; for (size_t x = 0; x < sizeof lower - 1; x++) putchar(x[lower]); ... You'll probably need to #include <stdio.h> and <stddef.h>... Do you see how I wrote x[lower] (with x being the integer type) rather than lower[x]? The C compiler doesn't care, because *(lower + x) is the same value as *(x + lower), and lower[x] is the former where-as x[lower] is the latter. All of these expressions are equivalent. Try them out... see for yourself, if you can't take my word...

        – autistic
        Jun 29 '18 at 2:56











      • ... and then of course there's this part, which I've placed my own emphasis into, but you really should read the entire quote without emphasis: "Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined." The same is true for functions, btw.

        – autistic
        Jun 29 '18 at 3:08











      • Ohh and on one final note, @C-Star-Puppy, Microsoft C++ is not a C compiler and hasn't been one for almost 20 years. You can enable C89 mode, suuuure, but we have evolved beyond the late 1980s in computing. For more on that topic, I suggest reading this article... and then switching to an actual C compiler such as gcc or clang for all of your C compilation, because you'll find there are so many packages that have adopted C99 features...

        – autistic
        Jun 29 '18 at 3:15

















      • "array[x] is really a shortcut for *(array + x), [...]" Are you sure about that???? See an exposition of their different behaviors: eli.thegreenplace.net/2009/10/21/….

        – C-Star-W-Star
        Jun 28 '18 at 19:30












      • Alas, @C-Star-Puppy, the one reference your resource appears to not mention at all is the C standard. That is the specification by which your compilers must adhere to legally call themselves C compilers. Your resource doesn't seem to be contradicting my information at all. Nonetheless, the standard actually has some examples such as this gem where it's revealed that array[index] is actually ptr[index] in disguise... "The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))" You can't refute the std

        – autistic
        Jun 29 '18 at 2:45











      • Try this demonstration, @C-Star-Puppy: int main(void) unsigned char lower[] = "abcdefghijklmnopqrstuvwxyz"; for (size_t x = 0; x < sizeof lower - 1; x++) putchar(x[lower]); ... You'll probably need to #include <stdio.h> and <stddef.h>... Do you see how I wrote x[lower] (with x being the integer type) rather than lower[x]? The C compiler doesn't care, because *(lower + x) is the same value as *(x + lower), and lower[x] is the former where-as x[lower] is the latter. All of these expressions are equivalent. Try them out... see for yourself, if you can't take my word...

        – autistic
        Jun 29 '18 at 2:56











      • ... and then of course there's this part, which I've placed my own emphasis into, but you really should read the entire quote without emphasis: "Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined." The same is true for functions, btw.

        – autistic
        Jun 29 '18 at 3:08











      • Ohh and on one final note, @C-Star-Puppy, Microsoft C++ is not a C compiler and hasn't been one for almost 20 years. You can enable C89 mode, suuuure, but we have evolved beyond the late 1980s in computing. For more on that topic, I suggest reading this article... and then switching to an actual C compiler such as gcc or clang for all of your C compilation, because you'll find there are so many packages that have adopted C99 features...

        – autistic
        Jun 29 '18 at 3:15
















      "array[x] is really a shortcut for *(array + x), [...]" Are you sure about that???? See an exposition of their different behaviors: eli.thegreenplace.net/2009/10/21/….

      – C-Star-W-Star
      Jun 28 '18 at 19:30






      "array[x] is really a shortcut for *(array + x), [...]" Are you sure about that???? See an exposition of their different behaviors: eli.thegreenplace.net/2009/10/21/….

      – C-Star-W-Star
      Jun 28 '18 at 19:30














      Alas, @C-Star-Puppy, the one reference your resource appears to not mention at all is the C standard. That is the specification by which your compilers must adhere to legally call themselves C compilers. Your resource doesn't seem to be contradicting my information at all. Nonetheless, the standard actually has some examples such as this gem where it's revealed that array[index] is actually ptr[index] in disguise... "The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))" You can't refute the std

      – autistic
      Jun 29 '18 at 2:45





      Alas, @C-Star-Puppy, the one reference your resource appears to not mention at all is the C standard. That is the specification by which your compilers must adhere to legally call themselves C compilers. Your resource doesn't seem to be contradicting my information at all. Nonetheless, the standard actually has some examples such as this gem where it's revealed that array[index] is actually ptr[index] in disguise... "The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))" You can't refute the std

      – autistic
      Jun 29 '18 at 2:45













      Try this demonstration, @C-Star-Puppy: int main(void) unsigned char lower[] = "abcdefghijklmnopqrstuvwxyz"; for (size_t x = 0; x < sizeof lower - 1; x++) putchar(x[lower]); ... You'll probably need to #include <stdio.h> and <stddef.h>... Do you see how I wrote x[lower] (with x being the integer type) rather than lower[x]? The C compiler doesn't care, because *(lower + x) is the same value as *(x + lower), and lower[x] is the former where-as x[lower] is the latter. All of these expressions are equivalent. Try them out... see for yourself, if you can't take my word...

      – autistic
      Jun 29 '18 at 2:56





      Try this demonstration, @C-Star-Puppy: int main(void) unsigned char lower[] = "abcdefghijklmnopqrstuvwxyz"; for (size_t x = 0; x < sizeof lower - 1; x++) putchar(x[lower]); ... You'll probably need to #include <stdio.h> and <stddef.h>... Do you see how I wrote x[lower] (with x being the integer type) rather than lower[x]? The C compiler doesn't care, because *(lower + x) is the same value as *(x + lower), and lower[x] is the former where-as x[lower] is the latter. All of these expressions are equivalent. Try them out... see for yourself, if you can't take my word...

      – autistic
      Jun 29 '18 at 2:56













      ... and then of course there's this part, which I've placed my own emphasis into, but you really should read the entire quote without emphasis: "Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined." The same is true for functions, btw.

      – autistic
      Jun 29 '18 at 3:08





      ... and then of course there's this part, which I've placed my own emphasis into, but you really should read the entire quote without emphasis: "Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type ''array of type'' is converted to an expression with type ''pointer to type'' that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined." The same is true for functions, btw.

      – autistic
      Jun 29 '18 at 3:08













      Ohh and on one final note, @C-Star-Puppy, Microsoft C++ is not a C compiler and hasn't been one for almost 20 years. You can enable C89 mode, suuuure, but we have evolved beyond the late 1980s in computing. For more on that topic, I suggest reading this article... and then switching to an actual C compiler such as gcc or clang for all of your C compilation, because you'll find there are so many packages that have adopted C99 features...

      – autistic
      Jun 29 '18 at 3:15





      Ohh and on one final note, @C-Star-Puppy, Microsoft C++ is not a C compiler and hasn't been one for almost 20 years. You can enable C89 mode, suuuure, but we have evolved beyond the late 1980s in computing. For more on that topic, I suggest reading this article... and then switching to an actual C compiler such as gcc or clang for all of your C compilation, because you'll find there are so many packages that have adopted C99 features...

      – autistic
      Jun 29 '18 at 3:15











      2














      When you're saying




      make an array holding an index number (int) of an indeterminate number of entities




      you're basically saying you're using "pointers", but one which is a array-wide local pointer instead of memory-wide pointer. Since you're conceptually already using "pointers" (i.e. id numbers that refers to an element in an array), why don't you just use regular pointers (i.e. id numbers that refers to an element in the biggest array: the whole memory).



      Instead of your objects storing a resource id numbers, you can make them store a pointer instead. Basically the same thing, but much more efficient since we avoid turning "array + index" into a "pointer".



      Pointers are not scary if you think of them as array index for the whole memory (which is what they actually are)






      share|improve this answer



























        2














        When you're saying




        make an array holding an index number (int) of an indeterminate number of entities




        you're basically saying you're using "pointers", but one which is a array-wide local pointer instead of memory-wide pointer. Since you're conceptually already using "pointers" (i.e. id numbers that refers to an element in an array), why don't you just use regular pointers (i.e. id numbers that refers to an element in the biggest array: the whole memory).



        Instead of your objects storing a resource id numbers, you can make them store a pointer instead. Basically the same thing, but much more efficient since we avoid turning "array + index" into a "pointer".



        Pointers are not scary if you think of them as array index for the whole memory (which is what they actually are)






        share|improve this answer

























          2












          2








          2







          When you're saying




          make an array holding an index number (int) of an indeterminate number of entities




          you're basically saying you're using "pointers", but one which is a array-wide local pointer instead of memory-wide pointer. Since you're conceptually already using "pointers" (i.e. id numbers that refers to an element in an array), why don't you just use regular pointers (i.e. id numbers that refers to an element in the biggest array: the whole memory).



          Instead of your objects storing a resource id numbers, you can make them store a pointer instead. Basically the same thing, but much more efficient since we avoid turning "array + index" into a "pointer".



          Pointers are not scary if you think of them as array index for the whole memory (which is what they actually are)






          share|improve this answer













          When you're saying




          make an array holding an index number (int) of an indeterminate number of entities




          you're basically saying you're using "pointers", but one which is a array-wide local pointer instead of memory-wide pointer. Since you're conceptually already using "pointers" (i.e. id numbers that refers to an element in an array), why don't you just use regular pointers (i.e. id numbers that refers to an element in the biggest array: the whole memory).



          Instead of your objects storing a resource id numbers, you can make them store a pointer instead. Basically the same thing, but much more efficient since we avoid turning "array + index" into a "pointer".



          Pointers are not scary if you think of them as array index for the whole memory (which is what they actually are)







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 21 '10 at 3:44









          Lie RyanLie Ryan

          47.5k10 gold badges77 silver badges127 bronze badges




          47.5k10 gold badges77 silver badges127 bronze badges





















              1














              Building on Matteo Furlans design, when he said "most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array". The difference in the "work in progress" below is that it doesn't double in size, it aims at using only what is required. I have also omitted safety checks for simplicity...Also building on brimboriums idea, I have tried to add a delete function to the code...



              The storage.h file looks like this...



              #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 */


              The storage.c file looks like this...



              #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;



              The main.c looks like this...



              #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);



              Look forward to the constructive criticism to follow...






              share|improve this answer

























              • If it is constructive criticism that you seek, better to post over at Code Review. That said, a couple of suggestions: it is imperative that code checks for success of calls to malloc() before attempting to use the allocation. In the same vein, it is a mistake to directly assign the result of realloc() to the pointer to the original memory being reallocated; if realloc() fails, NULL is returned, and code is left with a memory leak. It is much more efficient to double memory when resizing than to add 1 space at a time: fewer calls to realloc().

                – David Bowling
                Dec 9 '18 at 3:11






              • 1





                Not trying to rip anyone apart, just offering some constructive criticism, which may have been forthcoming even without your light-hearted closer ;)

                – David Bowling
                Dec 9 '18 at 3:17






              • 1





                While strict doubling may not be optimal, it is certainly better than increasing memory one byte (or one int, etc.) at a time. Doubling is a typical solution, but I don't think that there is any optimal solution that fits all circumstances. Here is why doubling is a good idea (some other factor such as 1.5 would be fine as well): if you begin with a reasonable allocation, you may not need to reallocate at all. When more memory is needed, the reasonable allocation is doubled, and so on. In this way you likely need only one or two calls to realloc().

                – David Bowling
                Dec 9 '18 at 13:58






              • 1





                For a large array, that might be one or two calls to realloc() vs. many thousands of calls to realloc(). Trim the allocation to final size with a final call to realloc(), and no excess memory is wasted.

                – David Bowling
                Dec 9 '18 at 13:59







              • 1





                I see that the result of realloc() is still being directly assigned to the original pointer. If realloc() fails, a NULL pointer is returned and would be so assigned. In this case, there would no longer be a pointer to the original memory (which has not been and can no longer be deallocated: memory leak). The right way to do this is: int *temp = realloc(/* ... */); if temp == NULL /* handle error */ else int_pointer = temp; . Also, no need to cast malloc() and friends. Consider int_pointer = malloc(sizeof *int_pointer);: idiomatic, less error-prone, maintainable.

                – David Bowling
                Dec 9 '18 at 14:18















              1














              Building on Matteo Furlans design, when he said "most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array". The difference in the "work in progress" below is that it doesn't double in size, it aims at using only what is required. I have also omitted safety checks for simplicity...Also building on brimboriums idea, I have tried to add a delete function to the code...



              The storage.h file looks like this...



              #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 */


              The storage.c file looks like this...



              #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;



              The main.c looks like this...



              #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);



              Look forward to the constructive criticism to follow...






              share|improve this answer

























              • If it is constructive criticism that you seek, better to post over at Code Review. That said, a couple of suggestions: it is imperative that code checks for success of calls to malloc() before attempting to use the allocation. In the same vein, it is a mistake to directly assign the result of realloc() to the pointer to the original memory being reallocated; if realloc() fails, NULL is returned, and code is left with a memory leak. It is much more efficient to double memory when resizing than to add 1 space at a time: fewer calls to realloc().

                – David Bowling
                Dec 9 '18 at 3:11






              • 1





                Not trying to rip anyone apart, just offering some constructive criticism, which may have been forthcoming even without your light-hearted closer ;)

                – David Bowling
                Dec 9 '18 at 3:17






              • 1





                While strict doubling may not be optimal, it is certainly better than increasing memory one byte (or one int, etc.) at a time. Doubling is a typical solution, but I don't think that there is any optimal solution that fits all circumstances. Here is why doubling is a good idea (some other factor such as 1.5 would be fine as well): if you begin with a reasonable allocation, you may not need to reallocate at all. When more memory is needed, the reasonable allocation is doubled, and so on. In this way you likely need only one or two calls to realloc().

                – David Bowling
                Dec 9 '18 at 13:58






              • 1





                For a large array, that might be one or two calls to realloc() vs. many thousands of calls to realloc(). Trim the allocation to final size with a final call to realloc(), and no excess memory is wasted.

                – David Bowling
                Dec 9 '18 at 13:59







              • 1





                I see that the result of realloc() is still being directly assigned to the original pointer. If realloc() fails, a NULL pointer is returned and would be so assigned. In this case, there would no longer be a pointer to the original memory (which has not been and can no longer be deallocated: memory leak). The right way to do this is: int *temp = realloc(/* ... */); if temp == NULL /* handle error */ else int_pointer = temp; . Also, no need to cast malloc() and friends. Consider int_pointer = malloc(sizeof *int_pointer);: idiomatic, less error-prone, maintainable.

                – David Bowling
                Dec 9 '18 at 14:18













              1












              1








              1







              Building on Matteo Furlans design, when he said "most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array". The difference in the "work in progress" below is that it doesn't double in size, it aims at using only what is required. I have also omitted safety checks for simplicity...Also building on brimboriums idea, I have tried to add a delete function to the code...



              The storage.h file looks like this...



              #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 */


              The storage.c file looks like this...



              #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;



              The main.c looks like this...



              #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);



              Look forward to the constructive criticism to follow...






              share|improve this answer















              Building on Matteo Furlans design, when he said "most dynamic array implementations work by starting off with an array of some (small) default size, then whenever you run out of space when adding a new element, double the size of the array". The difference in the "work in progress" below is that it doesn't double in size, it aims at using only what is required. I have also omitted safety checks for simplicity...Also building on brimboriums idea, I have tried to add a delete function to the code...



              The storage.h file looks like this...



              #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 */


              The storage.c file looks like this...



              #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;



              The main.c looks like this...



              #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);



              Look forward to the constructive criticism to follow...







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Dec 9 '18 at 13:49

























              answered Dec 9 '18 at 3:01







              user1687619



















              • If it is constructive criticism that you seek, better to post over at Code Review. That said, a couple of suggestions: it is imperative that code checks for success of calls to malloc() before attempting to use the allocation. In the same vein, it is a mistake to directly assign the result of realloc() to the pointer to the original memory being reallocated; if realloc() fails, NULL is returned, and code is left with a memory leak. It is much more efficient to double memory when resizing than to add 1 space at a time: fewer calls to realloc().

                – David Bowling
                Dec 9 '18 at 3:11






              • 1





                Not trying to rip anyone apart, just offering some constructive criticism, which may have been forthcoming even without your light-hearted closer ;)

                – David Bowling
                Dec 9 '18 at 3:17






              • 1





                While strict doubling may not be optimal, it is certainly better than increasing memory one byte (or one int, etc.) at a time. Doubling is a typical solution, but I don't think that there is any optimal solution that fits all circumstances. Here is why doubling is a good idea (some other factor such as 1.5 would be fine as well): if you begin with a reasonable allocation, you may not need to reallocate at all. When more memory is needed, the reasonable allocation is doubled, and so on. In this way you likely need only one or two calls to realloc().

                – David Bowling
                Dec 9 '18 at 13:58






              • 1





                For a large array, that might be one or two calls to realloc() vs. many thousands of calls to realloc(). Trim the allocation to final size with a final call to realloc(), and no excess memory is wasted.

                – David Bowling
                Dec 9 '18 at 13:59







              • 1





                I see that the result of realloc() is still being directly assigned to the original pointer. If realloc() fails, a NULL pointer is returned and would be so assigned. In this case, there would no longer be a pointer to the original memory (which has not been and can no longer be deallocated: memory leak). The right way to do this is: int *temp = realloc(/* ... */); if temp == NULL /* handle error */ else int_pointer = temp; . Also, no need to cast malloc() and friends. Consider int_pointer = malloc(sizeof *int_pointer);: idiomatic, less error-prone, maintainable.

                – David Bowling
                Dec 9 '18 at 14:18

















              • If it is constructive criticism that you seek, better to post over at Code Review. That said, a couple of suggestions: it is imperative that code checks for success of calls to malloc() before attempting to use the allocation. In the same vein, it is a mistake to directly assign the result of realloc() to the pointer to the original memory being reallocated; if realloc() fails, NULL is returned, and code is left with a memory leak. It is much more efficient to double memory when resizing than to add 1 space at a time: fewer calls to realloc().

                – David Bowling
                Dec 9 '18 at 3:11






              • 1





                Not trying to rip anyone apart, just offering some constructive criticism, which may have been forthcoming even without your light-hearted closer ;)

                – David Bowling
                Dec 9 '18 at 3:17






              • 1





                While strict doubling may not be optimal, it is certainly better than increasing memory one byte (or one int, etc.) at a time. Doubling is a typical solution, but I don't think that there is any optimal solution that fits all circumstances. Here is why doubling is a good idea (some other factor such as 1.5 would be fine as well): if you begin with a reasonable allocation, you may not need to reallocate at all. When more memory is needed, the reasonable allocation is doubled, and so on. In this way you likely need only one or two calls to realloc().

                – David Bowling
                Dec 9 '18 at 13:58






              • 1





                For a large array, that might be one or two calls to realloc() vs. many thousands of calls to realloc(). Trim the allocation to final size with a final call to realloc(), and no excess memory is wasted.

                – David Bowling
                Dec 9 '18 at 13:59







              • 1





                I see that the result of realloc() is still being directly assigned to the original pointer. If realloc() fails, a NULL pointer is returned and would be so assigned. In this case, there would no longer be a pointer to the original memory (which has not been and can no longer be deallocated: memory leak). The right way to do this is: int *temp = realloc(/* ... */); if temp == NULL /* handle error */ else int_pointer = temp; . Also, no need to cast malloc() and friends. Consider int_pointer = malloc(sizeof *int_pointer);: idiomatic, less error-prone, maintainable.

                – David Bowling
                Dec 9 '18 at 14:18
















              If it is constructive criticism that you seek, better to post over at Code Review. That said, a couple of suggestions: it is imperative that code checks for success of calls to malloc() before attempting to use the allocation. In the same vein, it is a mistake to directly assign the result of realloc() to the pointer to the original memory being reallocated; if realloc() fails, NULL is returned, and code is left with a memory leak. It is much more efficient to double memory when resizing than to add 1 space at a time: fewer calls to realloc().

              – David Bowling
              Dec 9 '18 at 3:11





              If it is constructive criticism that you seek, better to post over at Code Review. That said, a couple of suggestions: it is imperative that code checks for success of calls to malloc() before attempting to use the allocation. In the same vein, it is a mistake to directly assign the result of realloc() to the pointer to the original memory being reallocated; if realloc() fails, NULL is returned, and code is left with a memory leak. It is much more efficient to double memory when resizing than to add 1 space at a time: fewer calls to realloc().

              – David Bowling
              Dec 9 '18 at 3:11




              1




              1





              Not trying to rip anyone apart, just offering some constructive criticism, which may have been forthcoming even without your light-hearted closer ;)

              – David Bowling
              Dec 9 '18 at 3:17





              Not trying to rip anyone apart, just offering some constructive criticism, which may have been forthcoming even without your light-hearted closer ;)

              – David Bowling
              Dec 9 '18 at 3:17




              1




              1





              While strict doubling may not be optimal, it is certainly better than increasing memory one byte (or one int, etc.) at a time. Doubling is a typical solution, but I don't think that there is any optimal solution that fits all circumstances. Here is why doubling is a good idea (some other factor such as 1.5 would be fine as well): if you begin with a reasonable allocation, you may not need to reallocate at all. When more memory is needed, the reasonable allocation is doubled, and so on. In this way you likely need only one or two calls to realloc().

              – David Bowling
              Dec 9 '18 at 13:58





              While strict doubling may not be optimal, it is certainly better than increasing memory one byte (or one int, etc.) at a time. Doubling is a typical solution, but I don't think that there is any optimal solution that fits all circumstances. Here is why doubling is a good idea (some other factor such as 1.5 would be fine as well): if you begin with a reasonable allocation, you may not need to reallocate at all. When more memory is needed, the reasonable allocation is doubled, and so on. In this way you likely need only one or two calls to realloc().

              – David Bowling
              Dec 9 '18 at 13:58




              1




              1





              For a large array, that might be one or two calls to realloc() vs. many thousands of calls to realloc(). Trim the allocation to final size with a final call to realloc(), and no excess memory is wasted.

              – David Bowling
              Dec 9 '18 at 13:59






              For a large array, that might be one or two calls to realloc() vs. many thousands of calls to realloc(). Trim the allocation to final size with a final call to realloc(), and no excess memory is wasted.

              – David Bowling
              Dec 9 '18 at 13:59





              1




              1





              I see that the result of realloc() is still being directly assigned to the original pointer. If realloc() fails, a NULL pointer is returned and would be so assigned. In this case, there would no longer be a pointer to the original memory (which has not been and can no longer be deallocated: memory leak). The right way to do this is: int *temp = realloc(/* ... */); if temp == NULL /* handle error */ else int_pointer = temp; . Also, no need to cast malloc() and friends. Consider int_pointer = malloc(sizeof *int_pointer);: idiomatic, less error-prone, maintainable.

              – David Bowling
              Dec 9 '18 at 14:18





              I see that the result of realloc() is still being directly assigned to the original pointer. If realloc() fails, a NULL pointer is returned and would be so assigned. In this case, there would no longer be a pointer to the original memory (which has not been and can no longer be deallocated: memory leak). The right way to do this is: int *temp = realloc(/* ... */); if temp == NULL /* handle error */ else int_pointer = temp; . Also, no need to cast malloc() and friends. Consider int_pointer = malloc(sizeof *int_pointer);: idiomatic, less error-prone, maintainable.

              – David Bowling
              Dec 9 '18 at 14:18











              0














              To create an array of unlimited items of any sort of type:



              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);



              and how to use it:



              // 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;



              This vector/array can hold any type of item and it is completely dynamic in size.






              share|improve this answer



























                0














                To create an array of unlimited items of any sort of type:



                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);



                and how to use it:



                // 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;



                This vector/array can hold any type of item and it is completely dynamic in size.






                share|improve this answer

























                  0












                  0








                  0







                  To create an array of unlimited items of any sort of type:



                  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);



                  and how to use it:



                  // 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;



                  This vector/array can hold any type of item and it is completely dynamic in size.






                  share|improve this answer













                  To create an array of unlimited items of any sort of type:



                  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);



                  and how to use it:



                  // 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;



                  This vector/array can hold any type of item and it is completely dynamic in size.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 17 '18 at 23:44









                  Sebastian KarlssonSebastian Karlsson

                  1581 silver badge11 bronze badges




                  1581 silver badge11 bronze badges





















                      0














                      Well, I guess if you need to remove an element you will make a copy of the array despising the element to be excluded.



                      // 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);
                      //


                      Assume that getElement2BRemove(), copy2TempVector( void* ...) and fillFromTempVector(...) are auxiliary methods to handle the temp vector.






                      share|improve this answer

























                      • It's unclear if this is actually an answer to the question posed, or if it a comment.

                        – user1531971
                        Nov 27 '18 at 18:43











                      • It's an opinion for "how to" and I am asking for confirmation (Am I wrong?) IF someone has a better idea. ;)

                        – JOSMAR BARBOSA - M4NOV3Y
                        Nov 27 '18 at 18:59











                      • I guess I don't understand your last sentence. Since SO is not a threaded forum, open questions like this in answers look odd.

                        – user1531971
                        Nov 27 '18 at 19:02











                      • ok, now its an assertion. ...philosophers... ;)

                        – JOSMAR BARBOSA - M4NOV3Y
                        Nov 27 '18 at 19:55






                      • 1





                        I fixed up your last sentence to what I think you want to say.

                        – user1531971
                        Nov 27 '18 at 19:58















                      0














                      Well, I guess if you need to remove an element you will make a copy of the array despising the element to be excluded.



                      // 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);
                      //


                      Assume that getElement2BRemove(), copy2TempVector( void* ...) and fillFromTempVector(...) are auxiliary methods to handle the temp vector.






                      share|improve this answer

























                      • It's unclear if this is actually an answer to the question posed, or if it a comment.

                        – user1531971
                        Nov 27 '18 at 18:43











                      • It's an opinion for "how to" and I am asking for confirmation (Am I wrong?) IF someone has a better idea. ;)

                        – JOSMAR BARBOSA - M4NOV3Y
                        Nov 27 '18 at 18:59











                      • I guess I don't understand your last sentence. Since SO is not a threaded forum, open questions like this in answers look odd.

                        – user1531971
                        Nov 27 '18 at 19:02











                      • ok, now its an assertion. ...philosophers... ;)

                        – JOSMAR BARBOSA - M4NOV3Y
                        Nov 27 '18 at 19:55






                      • 1





                        I fixed up your last sentence to what I think you want to say.

                        – user1531971
                        Nov 27 '18 at 19:58













                      0












                      0








                      0







                      Well, I guess if you need to remove an element you will make a copy of the array despising the element to be excluded.



                      // 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);
                      //


                      Assume that getElement2BRemove(), copy2TempVector( void* ...) and fillFromTempVector(...) are auxiliary methods to handle the temp vector.






                      share|improve this answer















                      Well, I guess if you need to remove an element you will make a copy of the array despising the element to be excluded.



                      // 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);
                      //


                      Assume that getElement2BRemove(), copy2TempVector( void* ...) and fillFromTempVector(...) are auxiliary methods to handle the temp vector.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Nov 27 '18 at 21:39







                      user1531971

















                      answered Nov 27 '18 at 18:21









                      JOSMAR BARBOSA - M4NOV3YJOSMAR BARBOSA - M4NOV3Y

                      515 bronze badges




                      515 bronze badges












                      • It's unclear if this is actually an answer to the question posed, or if it a comment.

                        – user1531971
                        Nov 27 '18 at 18:43











                      • It's an opinion for "how to" and I am asking for confirmation (Am I wrong?) IF someone has a better idea. ;)

                        – JOSMAR BARBOSA - M4NOV3Y
                        Nov 27 '18 at 18:59











                      • I guess I don't understand your last sentence. Since SO is not a threaded forum, open questions like this in answers look odd.

                        – user1531971
                        Nov 27 '18 at 19:02











                      • ok, now its an assertion. ...philosophers... ;)

                        – JOSMAR BARBOSA - M4NOV3Y
                        Nov 27 '18 at 19:55






                      • 1





                        I fixed up your last sentence to what I think you want to say.

                        – user1531971
                        Nov 27 '18 at 19:58

















                      • It's unclear if this is actually an answer to the question posed, or if it a comment.

                        – user1531971
                        Nov 27 '18 at 18:43











                      • It's an opinion for "how to" and I am asking for confirmation (Am I wrong?) IF someone has a better idea. ;)

                        – JOSMAR BARBOSA - M4NOV3Y
                        Nov 27 '18 at 18:59











                      • I guess I don't understand your last sentence. Since SO is not a threaded forum, open questions like this in answers look odd.

                        – user1531971
                        Nov 27 '18 at 19:02











                      • ok, now its an assertion. ...philosophers... ;)

                        – JOSMAR BARBOSA - M4NOV3Y
                        Nov 27 '18 at 19:55






                      • 1





                        I fixed up your last sentence to what I think you want to say.

                        – user1531971
                        Nov 27 '18 at 19:58
















                      It's unclear if this is actually an answer to the question posed, or if it a comment.

                      – user1531971
                      Nov 27 '18 at 18:43





                      It's unclear if this is actually an answer to the question posed, or if it a comment.

                      – user1531971
                      Nov 27 '18 at 18:43













                      It's an opinion for "how to" and I am asking for confirmation (Am I wrong?) IF someone has a better idea. ;)

                      – JOSMAR BARBOSA - M4NOV3Y
                      Nov 27 '18 at 18:59





                      It's an opinion for "how to" and I am asking for confirmation (Am I wrong?) IF someone has a better idea. ;)

                      – JOSMAR BARBOSA - M4NOV3Y
                      Nov 27 '18 at 18:59













                      I guess I don't understand your last sentence. Since SO is not a threaded forum, open questions like this in answers look odd.

                      – user1531971
                      Nov 27 '18 at 19:02





                      I guess I don't understand your last sentence. Since SO is not a threaded forum, open questions like this in answers look odd.

                      – user1531971
                      Nov 27 '18 at 19:02













                      ok, now its an assertion. ...philosophers... ;)

                      – JOSMAR BARBOSA - M4NOV3Y
                      Nov 27 '18 at 19:55





                      ok, now its an assertion. ...philosophers... ;)

                      – JOSMAR BARBOSA - M4NOV3Y
                      Nov 27 '18 at 19:55




                      1




                      1





                      I fixed up your last sentence to what I think you want to say.

                      – user1531971
                      Nov 27 '18 at 19:58





                      I fixed up your last sentence to what I think you want to say.

                      – user1531971
                      Nov 27 '18 at 19:58

















                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3536153%2fc-dynamically-growing-array%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                      SQL error code 1064 with creating Laravel foreign keysForeign key constraints: When to use ON UPDATE and ON DELETEDropping column with foreign key Laravel error: General error: 1025 Error on renameLaravel SQL Can't create tableLaravel Migration foreign key errorLaravel php artisan migrate:refresh giving a syntax errorSQLSTATE[42S01]: Base table or view already exists or Base table or view already exists: 1050 Tableerror in migrating laravel file to xampp serverSyntax error or access violation: 1064:syntax to use near 'unsigned not null, modelName varchar(191) not null, title varchar(191) not nLaravel cannot create new table field in mysqlLaravel 5.7:Last migration creates table but is not registered in the migration table

                      은진 송씨 목차 역사 본관 분파 인물 조선 왕실과의 인척 관계 집성촌 항렬자 인구 같이 보기 각주 둘러보기 메뉴은진 송씨세종실록 149권, 지리지 충청도 공주목 은진현