1

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.

5 Answers 5

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

+1, a doubt: you said 'os blanks memory pages used by other proc' is it so? I mean why os should bother about setting a long memory range to zero. Is there any (obvious) reason for that ?
@Vikram.exe: imagine you have an application that processes credit card numbers; would you be happy if your deallocated memory pages would go untouched to completely unrelated processes?
No I would not be, so I will explicitly unset the memory content myself (from my program). The underlying OS wouldn't. right? Its an extra overhead for the OS to do such (probably unnecessary) operations.
@Vikram.exe: AFAIK all the modern preemptive OSes do it (or, at least, so says Tanenbaum :) ); IIRC it's a low-priority thread that blanks unused pages when there's nothing better to do (or when they are needed). Keep in mind that memory pages get reused not only when you deallocate memory, but also when there's not enough memory and the OS needs to swap out your memory pages to give physical RAM to another process who needs it; your process don't have any occasion to clean up the sensitive data by itself (also because the task switch is transparent to applications).
1

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.

Comments

1

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.

1 Comment

Oho, it's always a lot of fun to deal with the magic fp values :)
0

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

10 Comments

Peoro: if it doesn't initialise it then what is this -431602080.000000 ? that each block seem to have?
If you are running in debug mode then this should be a magic value that helps you see that you are using uninitialized data.
It could be whatever. It could be the value that portion of memory was containing before your call.
@Freddy, who knows? It depends on your operating system, malloc implementation and what's happened in your application so far. It could be different on the next run. It's undefined, don't rely on it and don't worry about it - you will have to initialise the allocated space anyway
If you try the calculator here babbage.cs.qc.edu/IEEE-754/Decimal.html you will find it is the hex value 0xCDCDCDCD. Presumably something initalises stuff to this for debugging?
|
0

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.

1 Comment

Thanks Prasoon. I see that I have to calloc from now on whenever I use malloc.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.