One of job interview questions on C pointers here is the following: what is null pointer assignment error?
I've googled for a while and don't see any reasonable explanation. What is that? Trying to write through a null pointer? Something architecture- or environment-specific? What exactly is that err开发者_如何转开发or?
http://www.faqs.org/qa/qa-3786.html
A NULL pointer assignment is a runtime error It occurs due to various reasons one is that your program has tried to access an illegal memory location. Illegal location means either the location is in the operating systems address space or in the other processes memory space. In stdio.h NULL is defined as 0 So whenever your program tries to access 0th location the operating system kills your program with runtime assignment error because the 0th location is in the operating systems address space and operating system doesn't allow access to its address space by user program .
Example code:
int* ptr = NULL;
*ptr = 3;
Explanation:
On almost every system, address 0 is reserved. System won't allow you to write to that location. If you try, you will get a runtime exception (access violation, segmentation fault, etc.).
I actually can not recall the source, but according to the source, this run time error is restricted to small and medium memory models being put into use by corresponding compiler. You see, as told before, the null pointer actually does not points to zero, in fact different compilers use different but fixed memory location to be used as null pointer.
Lets consider the case of TC compiler, this compiler places four zero bytes at the bottom of the data segment and TC copyright notice. TC also uses DS:0000 location, bottom of the data segment as null pointers location. So, assigning a value to this null pointer, would actully change the four bytes and probably, mess up the copyright notice.
Now, at the program termination, the four zeros and copyright banner are checked for any kind of alteration. If any alterations are found, it generates a Null Pointer Assignment error.
So, I think its not just the null pointer, any pointer that gets wild, if tries to access some key areas, you are greeted with Null Pointer Assignment Error.
There are many scenarios where you can see problems. But the key thing is, you did not allocate the memory correctly. The following code would produce Null pointer assignment error message after you run the program. Note: It will compile correctly.
void CopyMessage(char *p)
{
strcpy(p, "welcome");
}
void main()
{
char *src;
CopyMessage(src);
}
It is a run time error occurs when you try to point illegal memory space, usually address 0 which is reserved for OS.
My intent in this answer is supplemental to the most basic of concepts of a null pointer. This simplest definition, as listed in many places is whenever a base value pointing to an address gets assigned a '0' or NULL value because the zero page, 0th memory location is part of the operating systems address space and operating system doesn't allow access to its address space by the user's program. In such cases the pre-compiler or compiler may generate an error, or the error can be generated by the operating system itself during run time as a memory access violation.
The following discussion of null pointers is based on concepts contained in the programming that occurs at the machine level of a language that allows fine control and requires understanding of how variable space is addressed.
Most high level languages and compilers may prevent this from occurring with appropriate 'type' casting, and specifying an option base and making no mental miscalculations in indexing. 'C' as a language, without specifying the strictest of compiler parameters, is particularly prone to these types of errors, as well as less sophisticated machine based compiler or programming languages as found today in "pocket' processors.
However, since the inception of computers and programming languages the concept of a zero pointer error expanded to include any pointer that points to the 0th location in any protected memory location. But especially within the context of how a memory location that can be used to point to any memory location can be unintentionally overwritten to contain a null value. And here I examine this concept because of what I've called 'the error of 1' which occurs when programmers have to switch between option base '0' or option base '1'. This is a counting issue where we begin our count with '0' or '1' as in:
Option Base 0
[0,1,2,..,9] or
Option Base 1
[1,2,3,...,10]
for an array with 10 elements. An error of 1 can create a miscalculation which results in a pointer to the first memory location 'before' the array,
Option Base 1
0[1,2,3,...,10]
^
|Last memory location of another variable space 'before' this variable space
or the first position 'after' the array which by definition is out of bounds.
Option Base 0
[0,1,2,...,9]10
^
|First memory location of another variable after this variable
But, when dealing with programming that uses direct memory access, as in the original machine code of any language, an error of 1 can be tragic placing an unintended value a memory location outside of the intended range which in the case of variable space and using pointers is the variable space before or after the intended variable, which when the array is initialized or cleared creates a 'null' or 0 in an undesired location, and especially if it's an array of pointers a null pointer error in an unintended variable.
This is of course dependent upon how the variable space is structured and/or what type. Can be particularly troublesome if the variable or other storage address space is nested in the code. As I state earlier, many high level language compilers can circumvent most of this type of error; but, when writing specific subroutines in machine code, for whatever reason deemed necessary, one must take extra care to ensure that option base is explicitly defined and adhered to by practice if not compiler convention.
First, programmers recognize the necessity that both the program and the storage areas are clearly defined and that nothing, without express consent, should modify even a single bit of data. This is critical, with respect to a null pointer because the 0th memory location, in zero page area of the operating system is often used to store a stack which are memory locations pushed onto the stack for a return operation. Whether a system call pushes an address for a return operation (popping the return address from where the system was interrupted) due to a mask-able or non-mask-able interrupts, or because the programmer wants to push data, or a memory location to be later popped off of this stack. This is a protected area. Like any pointer to a valid memory address, one would not want to write to the wrong location, the 0th location is particularly susceptible if overwritten because variables are often null or have a value of 0 from an initial power up state, and thus a variable which has not been explicitly defined after power up, or has been intentionally initialized is likely to be zero.
In the case of the stack on zero page, or any stack containing return address, if values are pushed onto the stack, and not popped before a 'return' is encountered, the return value can be null or zero and the return points to the stack's memory location. This is a null pointer error, which may not generate an error but return the code pointer to an area that does not contain code, such as the middle of a stack. These exploits are well known and often used in methods to compromise a system's security to gain access by less scrupulous crackers; or can be used for ingenious access under special circumstances, or when accidental create all kinds of mischief where the source is difficult to determine.
As I stated, this description is outside the conventional definition of a null pointer error, but it can produce a null pointer nonetheless, though more often producing other errors, or none at all. It often gives no indication of its existence other than 'if or when' a program fails to perform as expected.
Here I provide additional non-conventional examples and definitions of potential sources of null pointer assignment errors, rather than defining conventional understanding which is more an error in programming convention than an error in programming logic.
This type of error (undefined, or null) is much rarer. But modern programming of 'pocket' processors, using bench top devices like an Arduino, Raspberry PI, AMD, or any other computer on a chip programming exists in a myriad of forms, many of which are as simple today as yesteryear, this null pointer problem still exists today and can occur even in the most sophisticated of systems. Additionally, companies that build their own variable or data structures are probably also the most likely people to see this type error nowadays. The intention is to show examples that can aid in recognition.
As was defined in older days, it was soon recognized that conditions which produce null pointer errors could also produce errors where the value of the pointer was unintentionally modified. Then, as a variable which is being used as a pointer and having been overwritten without the programmer's intent or knowledge, which could be a null, but could also be any other value. So, we find that an issue which can create a null pointer, can also create a non null pointer. The null pointer is a special case, which OFTEN creates an systematic error message; but, when those same conditions cause the pointer to take on a random or undetermined value instead of the original address where the data should reside, it now contains a null or unknown address which results in moving or storing data to an invalid or unwanted location potentially overwriting and corrupting that code or data.
Most will rightfully argue that this is NOT a null pointer error; and, they are completely 100% CORRECT! However, the roots of this error typically create strange often seen null pointer errors because more often the pointers will contain a 'null'! The point of this exercise in definition is to point out how the creation of null pointers can also lead to a problem which appears to have no indication of the original source of the problem. IOW, in concept there is no pointer to the problem. Because of the relationship to the creation of odd 'null' pointer issues, and in this case the subsequent lack of data that points to the source of the error because the pointer was NOT null and instead is 'undefined' old timers who have transitioned from top-down programming to object oriented event driven programming recognize this relationship and recognize this type of 'null' pointing error which appears to have no definable source.
Because this type failure, the corrupted data, or corrupted code may not immediately execute or get used at the time it is moved to an existing unused memory location. However, when the code or data does cause a problem at a later time in the run, there is no information on the 'real' location of the error because it is so far removed in time from the event that caused it. Whether it creates or assigns null pointers or creates some other corruption, it modifies code, and things can get weird, really weird.
To summarize, I define a null pointer as any null or undefined address used to point to a memory location regardless of what originally creates it. A null pointer assignment error, or many other errors, can be assigned to this issue and example.
In simpler architecture or programming environments, It can refer to any code which unintentionally ends up creating nulls as pointers, or creates a bug that in anyway halts the execution, like overwriting a byte in the return stack, overwriting code, code that accidentally stores a '0' in a bad location, existing code, or just as data in the wrong location, not just as an address.
So, while the examples above, work fine to define an example of a null pointer. So we expand the concept, A null pointer is any pointer which gets used as a variable pointer, and the address location of that variable for any one of multiple reasons now contains a 'null' or ANY unintended value that causes it to point to an undesirable memory location no matter how it got there, not just errors in programming logic or math calculation errors. IOW, not just a 0 in a pointer; more specifically a zero or undefined value in any memory location where that memory location was not the specific target and under other circumstances had an OTHER purpose for which it will now perform!
So, finally, one can get a null pointer error, and upon examining the pointer finds it contains a null; but, cannot find the code that placed the null into the pointer or assigned it. This is a broadest definition of null pointer assignment error, and is absolutely the worst case scenario of a null pointer error. When this occurs in a large program, it often results in the death of the program because if the error existed in previous versions, but was writing to unintended memory locations (which allowed the program to function or IOW) which was previously accessible but unallocated in earlier versions, the error goes unnoticed until the program gets expanded, and now that once previously unused memory location contains new code OR data which allows the old bug to now generate random errors in the new code or corrupts data!
For example: in an earlier version, the bad address value causes data to be written outside of the defined variable spaces, but goes unnoticed for several versions because the data is being written, and it being read, and the program and everything 'appears' OK! But, as the program expands, new code now exists relatively in the same relative address space as the memory where the original old bug had been incorrectly writing to the wrong memory location and no one noticed, whether one byte, or a whole block of data! But, now, there exists new code there. And when the program runs that particular code, today or tomorrow as whatever function that contains it is called, the new data gets corrupted by the old undiscovered bug.
Finding the 'original' error which existed a year earlier is now almost, if not completely, impossible to find.
Administrator and developer logic usually dictates, why should I look there, we know that code ran and worked just fine for that last several versions. But, now, part of the new code does not work, a major pieces are broken. We look and look and nothing does one find. It's as if the error doesn't exist, and yet it does. What's causing it, who suspects code written years earlier? Null pointers and many other errors are caused by this too. With understanding, and a good editor that can examine code directly, appropriate monitors to watch modified memory locations that trigger a halt to determine the code being executed at right time, even this can be found.
精彩评论