Array in for loop, C99 - c

I asked a previous question about declaring an array in a for loop, e.g.
for(i=0;i<=1000;i++){
float arrayone[(length[i])];
do a bunch of other stuff
}
Basically, I'm trying to do an array whose length can be varied based on what step the program is on. I don't want to keep the array data saved permanently (like arrayone[][]), since it's big and there's lots of steps.
So I was told it's legal to declare the array only within this scope like this. But will it try to store 1000 copies of the array by the end, which I don't want? I'm a beginner, so I don't understand the nuances of what the blocks really do.
The alternative for me is just to make an array outside of the loop which has the maximum length ever needed, and to overwrite that at every step.
Edit: The use for the array is: I have a global array. The arrays in the loop are filled with function results using that global array, to save computing. The arrays get manipulated,...,...,and finally are used to change the global array. Then they're not needed anymore.

But will it try to store 1000 copies of the array by the end, which I don't want?
No, at the beginning of each iteration a new array will be allocated, and, since the array goes out of scope at the end of the iteration, at that time it will be deallocated, so only one array exists at one time.
That is the point of automatic variables (which that array is). At the end of the scope in which they are declared (usually but not always delimited by braces) they are automatically deallocated.

After each iteration of your loop is done all the variables that were declared inside your loop will be destroyed, including your array. So only one copy of your array will be kept.
That being said, however, you should know that initializing the array outside your loop is probably better, because you won't have to allocate memory on the stack every iteration.
If you were dynamically allocating your array (which you're not in your example) like this:
for(i=0;i<=1000;i++){
float * arrayone = (float*)malloc(i * sizeof(float));
}
then you have a problem. Here the local variable is the pointer, which when it gets destroyed you can no longer access the memory you allocated. This is the case where you would end up with 1000 different arrays in memory at once. You could free your memory before the pointer is destroyed, but I maintain that having the array declared outside the loop is still better.

Related

Having issues with double pointers

I'm trying to write a program that reads multiple files and stores all the words in one array of strings. Here are some parts of the code:
This is the array that I'm supposed to put the words in:
I also dynamically allocate memory to this array and free it, so the issue is not that. For some reason, after the while loop, when I try to print out the array, it is empty, like nothing was written to it.
If you need any other parts of the code, let me know, I'll gladly post it.
Assuming that word_collection.all_words is valid for all indexes you're using, then the assignment
word_collection.all_words[wc_pos++] = word;
will make all elements of word_collection.all_words point to the exact same location: The first element of the single word array.
This is one problem, there's also another possible problem with this: If word is not a global variable, then as soon as the function that defines word returns, the life-time of word will end, making all those pointers invalid.
To solve both those problems you need to allocate memory for each element as well, and copy the string from word. This can be done by the commonly available strdup function:
word_collection.all_words[wc_pos++] = strdup(word);
Of course you have to remember to free all the pointers returned by strdup.

where are the variable stored that are initialized in main function in c?

In C language, I know that when a variable is dynamically initialized using malloc, it is stored in heap area. But where is the memory allocated when declaration of below kind is done and variables are initialized later.
int a[26];
or
int a[n]; //n is a variable and each element in array a is later initialized through a for loop.
My initial understanding is that like in java, here also all variables declared in main function are stored in stack area. My doubt is- Say, there is a function that takes the address of array "a" and changes its contents. To change the contents of "a", it should be able to access each element's address in "a". As the function itself is getting executed in the stack space on the top of main function, it cannot access array "a"'s contents directly. So, my doubt is where is array "a"'s memory allocated?
Usually, int a[n]; is called a variable length array, and the storage allocation is compiler dependent.
For example, gcc allocates VLAs in stack memory.
FWIW, the local variables are also usually stored in stack memory (minus the compiler optimization, if any).
arrays can be almost any length, they can be used to store thousands or even millions of objects, but the size must be decided when the array is created. Each item in the array is accessed by an index, which is just a number that indicates the position or slot where the object is stored in the array.
Array size stored in the computer physical memory

C - Newly declared array contaminated with values from other variables

I'm alarmed to see that a newly declared array is being contiminated with some random values and some partial values from other variables within my C program.
Here's the source code of my function. I'm basically writing some pseudo code in preparation for doing some complex XML parsing and file manipulation (think similar to a mail merge). Anyway I'm concerned if there are random values in my newly declared array. Why isn't it empty of values when I first declare it?
Do I really need to traverse my entire array to set it's elements to blank values before I begin assigning values or is it likely that there's something wrong with other variable declarations in my code?
Thank you for your help.
Regards,
Chris
void ShowArray(void)
{
char aryString[5][5][255];
sprintf(aryString[1][1],"AAAAA");
sprintf(aryString[1][2],"BBBBB");
sprintf(aryString[1][3],"CCCCC");
sprintf(aryString[1][4],"DDDDD");
sprintf(aryString[1][5],"EEEEE");
sprintf(aryString[2][1],"A2");
sprintf(aryString[2][2],"B2");
int numRow;
int numCol;
for (numRow=1;numRow < 6;numRow++)
{
for (numCol=1;numCol < 6;numCol++)
printf("%d,%d:%s\n", numRow, numCol,aryString[numRow][numCol]);
}
}
Unfortunately you have to initialise the values of every element in an array.
Having random values populating your array and variables when you first declare it is normal. This is because when your computer frees up memory, it doesn't reset them to zero. You computer just allows other programs to overwrite the values in those newly freed memory locations.
Those uninitiallized values are just leftovers from other functions.
A local variable in a function will have an initially undefined value. This is, in fact, what you want, since the alternative would be for the compiler to force an initialization that in most case you don't want, unavoidably slowing your function. It is your responsibility to ensure that any variable has been properly defined before trying to use its value. I have never found this to be a problem.
You are also writing to the [1][5]th string in your code with sprintf. Your aryString variable is of dimensions [5][5][255]. Remember that array indexing in C is 0-based. You should not go beyond the [1][4]th element. You might want to delete that line and try again, because you will end up corrupting your own data by yourself.
Yes, all auto(opposite to static, which is declared explicitly) variables you declare in a function calls for manual initialization. The compiler won't initialize it automatically because it don't know what do you want to be written to that memory. To make it write the default value, which is usually 00000000, to uninitialized variables, write char aryString[5][5][255] = {};, or more commonly, char aryString[5][5][255] = {0};.
Also, the value an uninitialized variable contains is not only a garbage value, but also likely a trap representation, and merely accessing it will cause undefined behavior.

Sentinel vs. passing around a count

I have a structure in C which contains an array on which I perform stack operations.
If the stack is full, I need to prevent pushing an element past the end of the array, and return an error condition.
Is it better style to include the size of the stack as an element of the structure, and pass that number of elements to the stack_push() function, or should I have a sentinel element at the end of the stack array?
How are you going to implement your stack_push() function?
If it requires scanning to the end of the array looking for an empty slot to insert the pushed element into, then you need a sentinel value anyway (e.g., NULL, if the array contains pointer elements). But note that the algorithm is going to be O(N).
On the other hand, keeping track of the number of active elements within the array allows your algorithm to be O(1) for pushes (and also for pops). It also saves you the trouble of allocating one extra element in the array, which may be significant if it's an array of structs.
Generally speaking, most stack data structures are implemented using an array and a counter.
What sentinel value would you use? Of course, you have to be sure that the caller of this function will definitely never use this value. It could be very confusing to debug if your function is stopping prematurely at a sentinel value that seems like a reasonable input.
For things like strings, it is easy to use a NULL to terminate because a string should never have a zero byte. However, if you start using sentinels in some places and not in others, it can start to get very confusing for developers that are trying to use your code.
I would say to use a size argument unless there is a VERY clear and obvious choice of sentinel, and probably not even then.

Arrays scoping in threads

How are arrays scoped in C? When do they ever get destroyed? (Note, also talk about if they can be passed even in p_threads)
They're scoped just like normal variables:
// in a function
int arrayA[300];
{
float arrayB[100];
// arrayA and arrayB available here
}
// arrayB out of scope, inaccessible.
// arrayA still available.
If you were to pass the array to a function, it would be valid as long as the array was still in scope at the calling site.
Arrays are scoped like any other primitive, struct or union. Nothing ever gets destroyed in C, though arrays can go out of scope.
Also, just like other types, arrays can be allocated on the heap by calling malloc() to allocate enough space to hold the desired number of elements, and treating the returned void * as a pointer to the first element. Such an array will be valid until you call free().
WRT Pthreads, again the rules are just as for any other type. If you define an array as an automatic (function-scope) variable, it will go out of scope as soon as the function returns; you cannot safely pass a pointer to such an array to another thread. But if you allocate an array on the heap, then you can pass a pointer to this array (to anything inside the array) anywhere you please, including another thread. Of course, you still need to ensure thread-safe access to the contents using appropriate synchronisation mechanisms.
There's absolutely no difference in scoping and lifetime rules between arrays and any other named entities in C language. I.e. arrays are not special in any way when it comes to scope and lifetime. They behave in that regard just like an ordinary int variable would.

Resources