Check if 2d pointer array has user defined value in C? - c

Sample code:
float** a;
a = (float**) malloc(numNodes * sizeof(float*));
for(int i=0; i<`numNodes`; i++)
{
a[i] = (float*)malloc((numNodes-1) * sizeof(float));
}
I am creating a dynamic 2d array above. Before populating, I noticed that each block in the array already holds this value: -431602080.000000 and not NULL. Why is this?
There are situations where not all spaces within the array are used.
So, my query is simple, Is there an elegant way to check if the each block has this default value or a user defined value?
Thanks in advance.

The content of memory allocated with malloc (as well as of variables allocated on the stack) is undefined, so it may very well be anything. Usually you get space filled with zeroes (because the OS blanks memory pages that were used by other processes) or residues of the previous use of those memory pages (this is often the case if the memory page belonged to your process), but this is what happens under the hood, the C standard does not give any guarantees.
So, in general there's no "default value" and no way to check if your memory has been changed; however you can init the memory blocks you use with magic values that you're sure that will not be used as "real data", but it'll be just a convention internal to your application.
Luckily, for floating point variables there are several magic values like quiet NaN you can use for this purpose; in general you can use the macro NAN defined in <math.h> to set a float to NaN.
By the way, you shouldn't read uninitialized floats and doubles, since the usual format they are stored in (IEEE 754) contains some magic values (like the signaling NaN) that can raise arithmetic exceptions when they are read, so if your uninitialized memory happens to contain such bit pattern your application will probably crash.

C runtimes are not required to initialize any memory that you didn't initialize yourself and the values that they hold are essentially random garbage left over from the last time that memory was used. You will have to set them all to NULL explicitly first or use calloc.

Extending the good answer of Matteo Italia:
The code of initialization of a single array would look like:
float* row;
row = malloc( numNodes*sizeof(float) );
for (int i=0; i<numNodes; ++i) {
row[i] = nanf(); // set a Not-a-Number magic value of type float
}
(I'll leave it up to you to change this for your multi-dimensional array)
Then somewhere:
float value = ...; // read the array
if (isnan(value)) {
// not initialized
} else {
// initialized - do something with this
}
One thing is important to remember: NaN == NaN will yield false, so it's best to use isnan(), not == to test for the presence of this value.

In C automatic variables doesn't get automatically initialized. You need to explicitly set your variable to 0, if it's what you want.
The same is true for malloc that does'n initialize the space on the heap it allocates. You can use calloc if you want to initialize it:
a = malloc( numNodes*sizeof(float*) ); // no need to initialize this
for ... {
a[i] = calloc( numNodes-1, sizeof(float) );
}

Before populating, I noticed that each block in the array already holds this value: -431602080.000000 and not NULL. Why is this?
malloc() doesn't initialize the memory which it allocates. You need to use calloc() if you want 0 initialization
void *calloc(size_t nelem, size_t elsize);
The calloc() function allocates unused space for an array of nelem elements each of whose size in bytes is elsize. The space shall be initialized to all bits 0.

Related

declaring an array vs allocating memory for it [duplicate]

This question already has answers here:
Difference between array type and array allocated with malloc
(9 answers)
Closed 5 years ago.
I wrote a function in C that takes 10 integer from the user and prints them out.
void memoryallocationtest(int number)
{
// allocate space for 10 integer
char *input = malloc( 32 * sizeof(char) );
long *x = malloc( number * sizeof(long) );
char *ptr;
printf("please enter 10 integer X consecutively, -2147483648 <= X <= 2147483647)\n");
/* promts user to enter ith integer
* converts input string to long value and saves result in x
*/
for(int i = 0; i < number; i++)
{
printf( "%i. Integer:", (i + 1) );
scanf( "%s", input );
x[i] = strtol( input, &ptr, 10 );
}
free(x);
free(input);
}
Is this an efficient way to do it?
Is there any point of allocating and freeing space for my char-array "input" or should I just declare it like char input[32]; or is that what happens implicit anyway?
Setting aside memory for an array of 10 integers statically is done like this (the data lives on the stack part of memory.)
int array[10];
As for dynamic allocation, the data lives on the heap.
int *array = (int *) malloc(sizeof(int) * 10);
Here is a simple image that roughly describes the memory layout of a typical program:
Is there any point of allocating and freeing space for my char-array "input" or should I just declare it like char input[32]; or is that what happens implicit anyway?
The advantage of dynamic allocation is that you need not know in advance how much memory you want to request from the OS. The disadvantage is that it is more difficult to manage dynamically allocated memory, and it is more susceptible to external fragmentation. When you use malloc, what you describes does not happen implicitly.
If you know in advance exactly how much memory you need (exactly how long your integer array is), there is no need to use dynamic allocation (malloc), and declaring the array like "char input[32];" is totally sufficient.
Continuing from my comment:
While your technical understanding of the syntax and proper use of memory allocation functions is fine, the function you provided does not make much sense. Static declaration of local variables will always be faster (e.g. more efficient) than dynamically allocating memory (if just by virtue of saving the function call overhead).
The choice between "Do I need to dynamically allocate?" is largely governed by (1) "is it too big to fit on the stack?", and (2) "what is the lifetime needed for the stored values?" C11 Standard (draft n1570) §6.2.4 Storage durations of objects
Your function (type void) returns no value and does nothing with the 10 int values stored in x. In that regard, as written, there is no need to dynamically allocate anything. Simply declaring a character array and array of long will provide automatic storage duration (e.g. for the life of function (e.g. scope) whithin which they are declared). As such, a more efficient implementation of your function would simply declare char input[32] = ""; and long x[10] = {0};
Note: when you declare arrays within a function, the memory for the array is only guaranteed to exist during the life of the funciton. Upon return, the function stack (and any variables declared local to that function) are destroyed (e.g. the memory is released for re-use), and any attempt to access the values of the array (or any variable local to that function) after the function returns results in Undefined Behavior.
Now regardless whether you return x and change your function type to long *, there is no need to dynamically allocate input, as that value is not returned.
However, if you do need to return a pointer to x so that the values you store are available back in the calling function, then you do need to dynamically allocate x as you have done. Why? When you dynamically allocate memory for x with malloc the lifetime extends from the time the memory is allocated, until it is deallocated (See §7.22.3 Memory management functions, in the link above). So you can dynamically allocate x in your function as you have done, and then declare your function as long *memoryallocationtest(int number) and return x to make the values available for use within the remainder of your program until you free (x);.
Which brings me to my final point. Your function, as written, fills x, then immediately frees x. While fine, in a real-world use of x, the free (x); call would not take place until you had finished making use of x in some meaningful way.
So in summary, there is no need to allocate for input, if either x won't fit on the stack, or you decide to return x; are true, then yes, a perfectly efficient way to provide memory for x is with malloc. If however, you are just using x in your function, and it will fit within the function stack, (it will until you reach several hundred thousand elements, architecture and compiler depdendent), then a simple declaration of an array of long is all you need.

C Array Memory Error?(Beginner)

When I try to print all the values in the array(which should be zero?), it starts printing 0's but at the end prints wonky numbers:
"(printing zeros)...0,0,0,0,0,0,0,1810432,0,1809600,0,1809600,0,0,0,5,0,3907584..."
When I extend the array, only at the end do the numbers start to mess up. Is this a memory limitation or something? Very confused, would greatly appreciate if anyone could help a newbie out.
Done in CS50IDE, not sure if that changes anything
int main()
{
int counter [100000];
for(int i = 0; i < 100000; i++)
{
printf("%i,", counter[i]);
}
}
Your array isn't initialized. You simply declare it but never actually set it. In C (and C++, Objective-C) you need to manually set a starting value. Unlike Python, Java, JavaScript or C# this isn't done for you...
which should be zero?
The above assertion is incorrect.
auto variables (variables declared within a block without the static keyword) are not initialized to any particular value when they are created; their value is indeterminate. You can't rely on that value being 0 or anything else.
static variables (declared at file scope or with the static keyword) are initialized to 0 or NULL, depending on type.
You can initialize all of the elements of the array to 0 by doing
int counter [100000] = {{0}};
If there are fewer elements in the initializer than there are elements in the array, then the extra elements are initialized as though they were static - 0 or NULL. So the first element is being explicitly initialized to 0, and the remaining 99999 elements are implicitly initialized to 0.
The reason why this is happening is because you reserved 100000*4 = 400000 bytes of memory but didn't write anything to it (didn't initialize it).
So therefore, garbage is printed if you access a memory location which hasn't been written to yet. The reason why 0's aren't printed is because we want optimization and don't want the compiler wasting time in writing to 100000 integer addresses and also the best practices expect a developer to never access a memory place that he has never written to or allocated yet. If you try printing:
printf("%d\n", counter[100000]);
This would also print a garbage value, but you didn't allocate that did you? It's because C/C++ don't restrict or raise errors when you try to do such operation unlike Java.
Try it yourself
for (int i=0; i<100000; i++) {
counter[i] = i;
printf("%d\n", counter[i]);
}
Now only numbers from 1,2,3....99999 will be printed on the screen.
When you declare an array in C, it does not set the elements to zero by default. Instead, it will be filled with whatever data last occupied that location in memory, which could be anything.
The fact that the first portion of the array contained zeros is just a coincidence.
This beginning state of an array is referred to as an "uninitialized" array, as you have not provided any initial values for the array. Before you can use the array, it should be "initialized", meaning that you specify a default value for each position.

Function that creates and returns an array is causing problems

I tried to write a function that returns a random array of pixel colors, so when I call randomPalette(i), the function will create a random array of i colors. Below are my codes. It says error at random[colors] that expression must have constant value. I don't know why. How to fix it?
pixel* randomPalette(int colors){
pixel random[colors] ;
int i, x;
srand(time(NULL)); //generate a random seed
for (i = 0; i < colors; i++){
x = rand() % 256;
random[i].r = x; random[i].g = x; random[i].b = x;
}
return random;
}
In your code, firstly
pixel random[colors] ;
syntax is called variable length array a.k.a VLA and only supported on and over C99. If you want this to work, you need to enforce your compiler to use C99 mode, like for gcc, you'll need to use --std=C99 compiler option.
Secondly, random is an automatic local variable and you're trying to return (the address of) it. If the returned value is being used, you'll invoke undefined behavior.
Solution: use a pointer and dynamic memory allocation, like malloc() and family. Dynamically allocated memory lifetime remains alive until deallocated manually by calling free(), so you can return the pointer from the function and use it in the caller, too.
Below are my codes. It says error at random[colors] that expression
must have constant value. I don't know why. How to fix it?
Apparently you don't have support for variable length arrays. Either use a fixed integer (such as #define or const integer) below instead of colors:
pixel random[colors] ;
or allocate memory dynamically. e.g.
pixel *random = malloc (sizeof(pixel) * colors);
But don't forget to free if you use approach as above.
Finally, you can't do this either:
return random;
because you are returning address to local variable which will go out of scope when function ends. Actually, you can return random if you initialize it using dynamic memory allocation such as with malloc. But if you don't use dynamic memory you can't return that.

C type conversion between NULL and integer

I have a question about type conversion in C.
So, I'm using these lines of code to initialize my index values to NULL:
frameTable[i].lv1Index = (int) NULL;
frameTable[i].lv2Index = (int) NULL;
where frameTable is constructed of the following:
typedef struct {
int lv2Index, lv1Index;
} Frame;
Frame* frameTable;
Can anyone tell me what is wrong with this?
This is my memory allocation:
frameTable = (Frame*) malloc(frameTableSize * sizeof(Frame));
NULL is a macro that represents the null pointer, not an integer. What you're doing is one of the most widespread and painful abuses that is causing the C++ standardisers no end of headache.
If you want an integer to be zero, use the octal 0 literal:
int n = 0;
Next, your code is fine, but missing the allocation. Where are the frameTable[i] variables stored?
You need one of the following two:
Frame frameTable[2]; // automatic storage
Frame * frameTable = malloc(sizeof(Frame) * 2); // manual, your responsibility now
This will probably compile and execute correctly since you're casting NULL to int (i.e., the compiler assumes you know what you're doing), but NULL is intended to be used with pointers. Since your structure fields are ints, just set them equal to zero to initialize them ("frameTable[i].lv1Index = 0;"). If you want to indicate that they are not valid indices yet, then set them to -1 or some other invalid value.
NULL is for pointers, not ints. While you can force the casting of just about anything, you're better off being more explicit and exact in setting them to 0.
You can also get the same effect by calloc'ing the memory (versus mallocing it) when you allocate your frameTable(s). Calloc clears all bytes to 0 in the memory that it allocates.
In c, besides pointers you cannot set c objects to NULL. You cannot cast NULL to other object since it encapsulates nothing. So you might want to set your struct variables to 0 instead of NULL.

How to check if "set" in c

If I allocate a C array like this:
int array[ 5 ];
Then, set only one object:
array[ 0 ] = 7;
How can I check whether all the other keys ( array[1], array[2], …) are storing a value? (In this case, of course, they aren't.)
Is there a function like PHP's isset()?
if ( isset(array[ 1 ]) ) ...
There isn't things like this in C. A static array's content is always "set". You could, however, fill in some special value to pretend it is uninitialized, e.g.
// make sure this value isn't really used.
#define UNINITIALIZED 0xcdcdcdcd
int array[5] = {UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED};
array[0] = 7;
if (array[1] != UNINITIALIZED) {
...
You can't
There values are all undefined (thus random).
You could explicitly zero out all values to start with so you at least have a good starting point. But using magic numbers to detect if an object has been initialized is considered bad practice (but initializing variables is considered good practice).
int array[ 5 ] = {};
But if you want to explicitly check if they have been explicitly set (without using magic numbers) since creation you need to store that information in another structure.
int array[ 5 ] = {}; // Init all to 0
int isSet[ 5 ] = {}; // Init all to 0 (false)
int getVal(int index) {return array[index];}
int isSet(int index) {return isSet[index];}
void setVal(int index,int val) {array[index] = val; isSet[index] = 1; }
In C, all the elements will have values (garbage) at the time of allocation. So you cannot really have a function like what you are asking for.
However, you can by default fill it up with some standard values like 0 or INT_MIN using memset() and then write an isset() code.
I don't know php, but one of two things is going on here
the php array is actually a hash-map (awk does that)
the php array is being filled with nullable types
in either case there is a meaningful concept of "not set" for the values of the array. On the other hand a c array of built in type has some value in every cell at all times. If the array is uninitialized and is automatic or was allocated on the heap those values may be random, but they exist.
To get the php behavior:
Implement (or find a library wit) and use a hashmap instead on an array.
Make it an array of structures which include an isNull field.
Initialize the array to some sentinal value in all cells.
One solution perhaps is to use a separate array of flags. When you assign one of the elements, set the flag in the boolean array.
You can also use pointers. You can use null pointers to represent data which has not been assigned yet. I made an example below:
int * p_array[3] = {NULL,NULL,NULL};
p_array[0] = malloc(sizeof(int));
*p_array[0] = (int)0;
p_array[2] = malloc(sizeof(int));
*p_array[2] = (int)4;
for (int x = 0; x < 3; x++) {
if (p_array[x] != NULL) {
printf("Element at %i is assigned and the value is %i\n",x,*p_array[x]);
}else{
printf("Element at %i is not assigned.\n",x);
}
}
You could make a function which allocates the memory and sets the data and another function which works like the isset function in PHP by testing for NULL for you.
I hope that helps you.
Edit: Make sure the memory is deallocated once you have finished. Another function could be used to deallocate certain elements or the entire array.
I've used NULL pointers before to signify data has not been created yet or needs to be recreated.
An approach I like is to make 2 arrays, one a bit-array flagging which indices of the array are set, and the other containing the actual values. Even in cases where you don't need to know whether an item in the array is "set" or not, it can be a useful optimization. Zeroing a 1-bit-per-element bit array is a lot faster than initializing an 8-byte-per-element array of size_t, especially if the array will remain sparse (mostly unfilled) for its entire lifetime.
One practical example where I used this trick is in a substring search function, using a Boyer-Moore-style bad-character skip table. The table requires 256 entries of type size_t, but only the ones corresponding to characters which actually appear in the needle string need to be filled. A 1kb (or 2kb on 64-bit) memset would dominate cpu usage in the case of very short searches, leading other implementations to throw around heuristics for whether or not to use the table. But instead, I let the skip table go uninitialized, and used a 256-bit bit array (only 32 bytes to feed to memset) to flag which entries are in use.

Resources