I was hoping to get help with the below question.
In VBA programming there is a syntax which can be used to assign the value vbNullstring to a variable before you assign any data to it, this way you ensure a fresh start to your variable and the data saved onto it.
How do you do the above in C language? I'm currently running a step-by-step debug of my code and I've added a few 'watch' processes to my key variables so that I can keep track of what my code is assigning it. Here's my confusion and hence the above question...my program has not even begun to assign any data to my variables and yet on my 'watch' tab i see that these variables are carrying different values already like 19924000669 for int variables and "(\0\002\0\0\0Ay..." for char variables. How do I get rid of these initial values and show an empty initial value for all my variables before the code assigns any data to it?
Thanks,
J
There are no "initial" values in C. Or rather, there are no meaningful values - C doesn't require that the compiler initialize variables to any value (some compilers do, so it depends on the compiler - read your compiler manual).
What you're seeing is "noise". When you turn on your computer, the value of data in your RAM is random. Set by various physical processes from thermal noise to cosmic background radiation. Also, when you're running a program in an OS, when you free some memory back to the OS or when your program quits the OS generally doesn't reformat that memory to any value. So you may also be seeing data that's there from previous running programs.
The traditional solution in C is to initialize the variable with the value zero (0) or if it's a pointer, NULL.
If you need to know if something is actually data or uninitialized then use a struct with a member (something called defined?) that keeps track of the initialized state and set that to 0 or 1. That's what VB (or Javascript or Perl etc.) is doing behind the scenes anyway.
C doesn't have the "feature" of undefined values because C deals directly with hardware. And bits are either on or off - digital electronics doesn't really like any other values - so variables muse be either 0 or not 0.
When you declare a variable you can specify an initial value, e.g.
int intvar = 0;
char str[10] = "";
Related
I'm currently working on a program which picks up input(via main) and draws different fractals depending on the input.
I'm saving the parsed and converted(to a number)user input, in a structure:
typedef struct
{
unsigned int xcord,ycord;
}point_t;
typedef struct
{
int fractalType;
double lstart,lend,lconstant;
double leftangle,rightangle;
point_t drawStart;
}input_data_t;
The problem I'm having is that certain fractals don't use all the variables contained in the structure, and if a certain fractal is called with a variables it doesn't use I must show an error.
Anyways now on to the problem, I know that variables when DECLARED "pick up " garbage from what was before hand in the assigned memory position. Is there any way to know if a variable has been initialized during run time, as to insure after parsing that no unnecessary variable has been used? (If so I need a cross platform solution)
No, there is no way to find this out directly. Reading from an uninitialized variable invokes undefined behavior and there is no way to recover from that. However, you have a few options to prevent this from happening.
If your variables have meaningful default values, just initialize them to those defaults before doing anything else with them. You still won't be able to tell the difference between a variable that was defaulted and one that just happens to have the same value but if your logic works without that knowledge, then this is perfectly fine. (For example, if you were to plot a sine function f(x) = a + b sin(c x + d), it would be natural to default a and d to 0 and b and c to 1.)
If your parameters don't span the entire value range of the data type, you could initialize them to some sentinel value and check for that before using them. For example, you could use NAN for floating-point values or −1 for quantities of any type that cannot be negative. Many people dislike this solution because it is all too easy to forget checking the value and using the sentinel as if it were a proper value, thus computing garbage. I believe that there is a time and place for every technique but this one is probably indeed overused.
If everything else fails, you can add a flag per variable that indicates whether it has a value. To make this usable, I recommend you create a data type with a reasonable name such as this one.
struct optional_float
{
bool initialized; // always safe to read, set appropriately
float value; // only safe to read if initialized == true
};
In C++, you can do much better by using the new std::experimental::optional<T>. But I realize that the C++ tag was removed from your question.
Finally, be sure to run your code through a debugger such as Valgrind or use a sanitizer to detect accidental reads from uninitialized variables.
I don't think there is method to check a variable wether initialiez or not .
As default variable in c has a random value or 0 before you initialize it.
If you want to know wether a variable is initialzed ,you can make a legal value scope of this variable. Before you use it ,you can check wether the value is inside the scope.
The best method in c to safty using variables is checking it by yourself if you are to use it.
why not just initialize that struct with some invalid value, then the problem become whether the value is invalid.
I'm still wondering why in C you can't simply set something to be another thing using plain variables. A variable itself is a pointer to data, is it not? So why make pointers point to the data in the variable when you can simply use the original variable? Is it to access specific bits (or bytes, I guess) of data within said variable?
I'm sure it's logical, however I have never fully grasped the concept and when reading code seeing *pointers always throws me off.
One common place where pointers are helpful is when you are writing functions. Functions take their arguments 'by value', which means that they get a copy of what is passed in and if a function assigns a new value to one of its arguments that will not affect the caller. This means that you couldn't write a "doubling" function like this:
void doubling(int x)
{
x = x * 2;
}
This makes sense because otherwise what would the program do if you called doubling like this:
doubling(5);
Pointers provide a tool for solving this problem because they let you write functions that take the address of a variable, for example:
void doubling2(int *x)
{
(*x) = (*x) * 2;
}
The function above takes the address of an integer as its argument. The one line in the function body dereferences that address twice: on the left-hand side of the equal sign we are storing into that address and on the right-hand side we are getting the integer value from that address and then multiply it by 2. The end result is that the value found at that address is now doubled.
As an aside, when we want to call this new function we can't pass in a literal value (e.g. doubling2(5)) as it won't compile because we are not properly giving the function an address. One way to give it an address would look like this:
int a = 5;
doubling2(&a);
The end result of this would be that our variable a would contain 10.
A variable itself is a pointer to data
No, it is not. A variable represents an object, an lvalue. The concept of lvalue is fundamentally different from the concept of a pointer. You seem to be mixing the two.
In C it is not possible to "rebind" an lvalue to make it "point" to a different location in memory. The binding between lvalues and their memory locations is determined and fixed at compile time. It is not always 100% specific (e.g. absolute location of a local variable is not known at compile time), but it is sufficiently specific to make it non-user-adjustable at run time.
The whole idea of a pointer is that its value is generally determined at run time and can be made to point to different memory locations at run time.
No, a variable is not a pointer to data. If you declare two integers with int x, y;, then there is no way to make x and y refer to the same thing; they are separate.
Whenever you read or write from a variable, your computer has to somehow determine the exact location of that variable in your computer's memory. Your computer will look at the code you wrote and use that to determine where the variable is. A pointer can represent the situation where the location is not known at the time when you compile your code; the exact address is only computed later when you actually run your code.
If you weren't allowed to use pointers or arrays, every line of code you write would have to access specific variables that are known at compile time. You couldn't write a general piece of code that reads and writes from different places in memory that are specified by the caller.
Note: You can also use arrays with a variable index to access variables whose location is not known at compile time, but arrays are mostly just syntactical sugar for pointers. You can think about all array operations in terms of pointer operations instead. Arrays are not as flexible as pointers.
Another caveat: As AnT points out, the location of local variables is usually on the stack, so they are a type of variable where the location isn't known at compile time. But the only reason that the stack works for storing local variables in a reentrant function is that your compiler implements hidden pointers called the stack pointer and/or frame pointer, and functions use these pointers to find out which part of memory holds their arguments and local variables. Pointers are so useful that the compiler actually uses them behind your back without telling you.
Another reason: C was designed to build operating systems and lots of low level code that deals with hardware. Every piece of hardware exposes its interface by means of registers, and on nearly all architectures, registers are mapped into the CPU memory space, and they have not to be in the same address always (thanks to jumper settings, PnP, autoconfig, and so on)
So the OS writer, while writing a driver for instance, needs a way to deal with what seems memory locations, only that they don't refer RAM cells.
Pointers serve to this purpose by allowing the OS writer to specify what memory location he or she wants to access to.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What happens to a declared, uninitialized variable in C? Does it have a value?
Now I'm reading Teach Yourself C in 21 Days. In chapter 3, there is a note like this:
DON'T use a variable that hasn't been initialized. Results can be
unpredictable.
Please explain to me why this is the case. The book provide no further clarification about it.
Because, unless the variable has static storage space, it's initial value is indeterminate. You cannot rely on it being anything as the standard does not define it. Even statically allocated variables should be initialized though. Just initialize your variables and avoid a potential headache in the future. There is no good reason to not initialize a variable, plenty of good reasons to do the opposite.
On a side note, don't trust any book that claims to teach you X programming language in 21 days. They are lying, get yourself a decent book.
When a variable is declared, it will point to a piece of memory.
Accessing the value of the variable will give you the contents of that piece of memory.
However until the variable is initialised, that piece of memory could contain anything. This is why using it is unpredictable.
Other languages may assist you in this area by initialising variables automatically when you assign them, but as a C programmer you are working with a fairly low-level language that makes no assumptions about what you want to do with your program. You as the programmer must explicitly tell the program to do everything.
This means initialising variables, but it also means a lot more besides. For example, in C you need to be very careful that you de-allocate any resources that you allocate once you're finished with them. Other languages will automatically clean up after you when the program finished; but in C if you forget, you'll just end up with memory leaks.
C will let you get do a lot of things that would be difficult or impossible in other languages. But this power also means that you have to take responsibility for the housekeeping tasks that you take for granted in those other languages.
You might end up using a variable declared outside the scope of your current method.
Consider the following
int count = 0;
while(count < 500)
{
doFunction();
count ++;
}
...
void doFunction() {
count = sizeof(someString);
print(count);
}
In C, using the values of uninitialized automatic variables (non-static locals and parameter variables) that satisfy the requirement for being a register variable is undefined behavior, because such variables values may have been fetched from a register and certain platforms may abort your program if you read such uninitialized values. This includes variables of type unsigned char (this was added to a later C spec, to accommodate these platforms).
Using values of uninitialized automatic variables that do not satisfy the requirement for being a register variable, like variables that have their addresses taken, is fine as long as the C implementation you use hasn't got trap representations for the variable type you use. For example if the variable type is unsigned char, the Standard requires all platforms not to have trap representations stored in such variables, and a read of an indeterminate value from it will always succeed and is not undefined behavior. Types like int or short don't have such guarantees, so your program may crash, depending on the C implementation you use.
Variables of static storage duration are always initialized if you don't do it explicitly, so you don't have to worry here.
For variables of allocated storage duration (malloc ...), the same applies as for automatic variables that don't satisfy the requirements for being a register variable, because in these cases the affected C implementations need to make your program read from memory, and won't run into the problems in which register reads may raise exceptions.
In C the value of an uninitialized variable is indeterminate. This means you don't know its value and it can differ depending on platform and compiler. The same is also true for compounds such as struct and union types.
Why? Sometimes you don't need to initialize a variable as you are going to pass it to a function that fills it and that doesn't care about what is in the variable. You don't want the overhead of initialization imposed upon you.
How? Primitive types can be initialized from literals or function return values.
int i = 0;
int j = foo();
Structures can be zero intialized with the aggregate intializer syntax:
struct Foo { int i; int j; }
struct Foo f = {0};
At the risk of being pedantic, the statement
DON'T use a variable that hasn't been initialized.
is incorrect. If would be better expressed:
Do not use the value of an uninitialised variable.
The language distinguishes between initialisation and assignment, so the first warning is, in that sense over cautious - you need not provide an initialiser for every variable, but you should have either assigned or initialised a variable with a useful and meaningful value before you perform any operations that subsequently use its value.
So the following is fine:
int i ; // uninitialised variable
i = some_function() ; // variable is "used" in left of assignment expression.
some_other_function( i ) ; // value of variable is used
even though when some_function() is called i is uninitialised. If you are assigning a variable, you are definitely "using" it (to store the return value in this case); the fact that it is not initialised is irrelevant because you are not using its value.
Now if you adhere to
Do not use the value of an uninitialised variable.
as I have suggested, the reason for this requirement becomes obvious - why would you take the value of a variable without knowing that it contained something meaningful? A valid question might then be "why does C not initialise auto variables with a known value. And possible answers to that would be:
Any arbitrary compiler supplied value need not be meaningful in the context of the application - or worse, it may have a meaning that is contrary to the actual state of the application.
C was deliberately designed to have no hidden overhead due to its roots as systems programming language - initialisation is only performed when explicitly coded, because it required additional machine instructions and CPU cycles to perform.
Note that static variables are always initialised to zero. .NET languages, such as C# have the concept of an null value, or a variable that contains nothing, and that can be explicitly tested and even assigned. A variable in C cannot contain nothing, but what it contains can be indeterminate, and therefore code that uses its value will behave non-deterministically.
Why do the variables take garbage values?
I guess the rationale for this is that your program will be faster.
If compiler automatically reset (ie: initialize to 0 or to NaN for float/doubles etc etc) your variables, it would take some time doing that (it'd have to write to memory).
In many cases initializing variables could be unneeded: maybe you will never access your variable, or will write on it the first time you access it.
Today this optimization is arguable: the overhead due to initializing variables is maybe not worth the problems caused by variables uninitialized by mistake, but when C has been defined things were different.
Unassigned variables has so-called indeterminate state that can be implemented in whatever way, usually by just keeping unchanged whatever data was in memory now occupied by the variable.
It just takes whatever is in memory at the address the variable is pointing to.
When you allocate a variable you are allocating some memory. if you dont overwrite it, memory will contain whatever "random" information was there before and that is called garbage value.
Why would it not? A better question might be "Can you explain how it comes about that a member variable in C# which is not initialised has a known default value?"
When variable is declared in C, it involves only assigning memory to variable and no implicit assignment. Thus when you get value from it, it has what is stored in memory cast to your variable datatype. That value we call as garbage value. It remains so, because C language implementations have memory management which does not handle this issue.
This happens with local variables and memory allocated from the heap with malloc(). Local variables are the more typical mishap. They are stored in the stack frame of the function. Which is created simply by adjusting the stack pointer by the amount of storage required for the local variables.
The values those variables will have upon entry of the function is essentially random, whatever happened to be stored in those memory locations from a previous function call that happened to use the same stack area.
It is a nasty source of hard to diagnose bugs. Not in the least because the values aren't really random. As long as the program has predictable call patterns, it is likely that the initial value repeats well. A compiler often has a debug feature that lets it inject code in the preamble of the function that initializes all local variables. A value that's likely to produce bizarre calculation results or a protected mode access violation.
Notable perhaps as well is that managed environments initialize local variables automatically. That isn't done to help the programmer fall into the pit of success, it's done because not initializing them is a security hazard. It lets code that runs in a sandbox access memory that was written by privileged code.
When we create a variable and don't initialize it, then some (random) number called garbage value is assigned to it.
How this value is assigned to the variable?
What is whole concept/mechanism behind this?
Does this happen only in C?
The garbage value is not assigned, rather the value is already there. When you allocate a variable you are reserving a piece of memory - until you overwrite it that memory will contain whatever "random" information was there before.
As a metaphor, think of allocating a variable like buying a piece of land - until you do something with it (like build a house) the land will just have whatever trash was already sitting there (like an old crumbling house).
Some languages will automatically fill newly allocated variables with zeros - this takes time to do. In more "do-it-yourself" languages like C this extra behavoir is not guarenteed (though on some systems memory is cleared regardless of language, for example as a security measure)
Memory is used and reused at various points in your application. For example, as the call stack of your application grows and shrinks the same location in memory may be overwritten many, many times. The thing to remember is that as a piece of memory is abandoned it is not zeroed out, so if you do not specify a new initial value for that place in memory when you use it again you will get the old, "garbage" value.
Some languages and structure implementations do default-initialize memory as it is used. Others do not, so it is important to read the documentation of your language carefully to know what to expect.
Nobody explicitly assigns a grabage value. If you create a variable, only location of the variable is determined, and not its value. Thats why we are initializing it. The garbage value might come from some previous operations over the same memory by old processes! So it can hold anything. I think it holds to pretty good number of languages. I am not sure about the list! :)
When we create a variable and don't initialize it, then nothing happens. When you read value from that variable you get data from memory where variable located now. It could looks like garbage/random value only because variables are placed in memory with some degree of randomness.
C standards say:
undefined behavior for local variables: (Why) is using an uninitialized variable undefined behavior? (e.g. segfault is legal)
zero for global variables: What happens to a declared, uninitialized variable in C? Does it have a value?
Implementation: detailed examination of an implementation at: https://stackoverflow.com/a/36725211/895245 Summary:
local: the address is never written to, so whatever was there previously gets used
global: .bss