C语言 什么是“空指针赋值错误”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2763617/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is "null pointer assignment error"?
提问by sharptooth
One of job interview questions on C pointers hereis the following: what is null pointer assignment error?
这里关于 C 指针的求职面试问题之一如下:什么是空指针分配错误?
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 error?
我用谷歌搜索了一段时间,没有看到任何合理的解释。那是什么?试图通过空指针写入?特定于架构或环境的东西?那个错误究竟是什么?
回答by Paya
http://www.faqs.org/qa/qa-3786.html
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 .
NULL 指针分配是一种运行时错误 它的发生有多种原因,其中之一是您的程序试图访问非法内存位置。非法位置意味着该位置位于操作系统地址空间或其他进程内存空间中。在 stdio.h 中 NULL 被定义为 0 因此,每当您的程序尝试访问第 0 个位置时,操作系统都会因运行时分配错误而终止您的程序,因为第 0 个位置位于操作系统地址空间中,并且操作系统不允许访问其地址空间由用户程序。
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.).
说明:
在几乎每个系统上,地址 0 都是保留的。系统不允许您写入该位置。如果您尝试,您将获得运行时异常(访问冲突、分段错误等)。
回答by Paras
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.
让我们考虑一下 TC 编译器的情况,这个编译器在数据段和 TC 版权声明的底部放置了四个零字节。TC 也使用 DS:0000 位置,数据段底部作为空指针位置。所以,给这个空指针赋值,实际上会改变四个字节,并且可能会弄乱版权声明。
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.
所以,我认为它不仅仅是空指针,任何变得疯狂的指针,如果试图访问某些关键区域,你会遇到空指针分配错误。
回答by MKG
It is a run time error occurs when you try to point illegal memory space, usually address 0 which is reserved for OS.
这是当您尝试指向非法内存空间时发生的运行时错误,通常是为 OS 保留的地址 0。
回答by Kathir Softwareandfinance
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);
}
回答by Cyberchipz
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.
我在这个答案中的意图是对空指针的最基本概念的补充。这个最简单的定义,如在许多地方列出的那样,每当指向地址的基值被分配一个“0”或 NULL 值时,因为零页、第 0 个内存位置是操作系统地址空间的一部分,而操作系统不允许用户程序访问其地址空间。在这种情况下,预编译器或编译器可能会生成错误,或者操作系统本身会在运行时作为内存访问冲突生成错误。
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.
大多数高级语言和编译器可以通过适当的“类型”转换来防止这种情况发生,并指定一个选项基础并且在索引中不会产生心理上的错误计算。“C”作为一种语言,没有指定最严格的编译器参数,特别容易出现这些类型的错误,以及今天在“袖珍”处理器中发现的不太复杂的基于机器的编译器或编程语言。
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 protectedmemory location. But especially within the context of how a memory location that can be used to point to anymemory 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:
然而,自从计算机和编程语言出现以来,零指针错误的概念扩展到包括指向任何受保护内存位置中第 0 个位置的任何指针。但尤其是在可用于指向任何内存位置的内存位置如何被无意覆盖以包含空值的上下文中。在这里我检查了这个概念,因为我称之为“错误 1”,当程序员必须在选项基“0”或选项基“1”之间切换时会发生这种情况。这是一个计数问题,我们以“0”或“1”开始计数,如下所示:
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,
对于具有 10 个元素的数组。错误 1 会造成计算错误,导致指向数组“之前”的第一个内存位置的指针,
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.
但是,在处理使用直接内存访问的编程时,如在任何语言的原始机器代码中,错误 1 可能是悲剧性的,将意外值放置在预期范围之外的内存位置,在变量空间和使用的情况下指针是预期变量之前或之后的变量空间,当数组被初始化或清除时,它会在不需要的位置创建一个“空”或 0,特别是如果它是一个指针数组,一个非预期变量中的空指针错误。
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.
这当然取决于变量空间的结构和/或类型。如果变量或其他存储地址空间嵌套在代码中,则可能特别麻烦。正如我之前所说,许多高级语言编译器可以规避大部分此类错误;但是,当在机器代码中编写特定的子程序时,无论出于何种原因认为必要,都必须格外小心,以确保选项 base 被明确定义并被实践遵守,如果不是编译器约定。
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.
首先,程序员认识到明确定义程序和存储区域的必要性,未经明确同意,不得修改哪怕是一点数据。这对于空指针来说是至关重要的,因为操作系统的零页区域中的第 0 个内存位置通常用于存储堆栈,堆栈是为了返回操作而压入堆栈的内存位置。由于可屏蔽或不可屏蔽的中断,或者因为程序员想要推送数据或内存位置,系统调用是否为返回操作推送地址(从系统中断的地方弹出返回地址)稍后会从这个堆栈中弹出。这是一个保护区。就像任何指向有效内存地址的指针一样,人们不希望写入错误的位置,
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.
这种类型的错误(未定义或空值)很少见。但是,使用 Arduino、Raspberry PI、AMD 等台式设备或任何其他芯片上的计算机编程的“袖珍”处理器的现代编程存在多种形式,其中许多形式今天和过去一样简单,这个空指针问题今天仍然存在,即使在最复杂的系统中也可能发生。此外,构建自己的变量或数据结构的公司可能也是当今最有可能看到此类错误的人。目的是展示有助于识别的示例。
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 cancreate a null pointer, can also create a non nullpointer. 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 thisis NOTa 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 sourceof 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 NOTnull 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.
大多数人会理所当然地认为,这是不是一个空指针错误; 而且,它们完全 100%正确!然而,这个错误的根源通常会产生奇怪的经常看到的空指针错误,因为指针通常会包含一个“空”!这个定义练习的重点是指出空指针的创建如何也会导致一个问题,这个问题似乎没有表明问题的原始来源。IOW,在概念上没有指向问题的指针。由于与创建奇数“空”指针问题的关系,并且在这种情况下,随后缺少指向错误源的数据,因为指针不是null 而不是“未定义”的旧计时器,他们已经从自上而下的编程过渡到面向对象的事件驱动编程,他们认识到这种关系并认识到这种似乎没有可定义来源的“空”指向错误。
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.
在更简单的体系结构或编程环境中,它可以引用任何无意中将空值创建为指针的代码,或者创建一个以任何方式停止执行的错误,例如覆盖返回堆栈中的一个字节、覆盖代码、意外存储的代码'0' 位于错误位置、现有代码或作为错误位置的数据,而不仅仅是地址。
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 ANYunintended 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 thatmemory location was not the specific target and under other circumstances had an OTHER purpose for which it will now perform!
所以,虽然上面的例子很好地定义了一个空指针的例子。所以我们扩展这个概念,空指针是用作变量指针的任何指针,并且由于多种原因中的任何一个,该变量的地址位置现在包含一个“空”或任何导致它指向一个的非预期值不受欢迎的内存位置,无论它是如何到达那里的,不仅仅是编程逻辑错误或数学计算错误。IOW,不仅仅是指针中的 0;更具体地说,在任何内存位置中的零或未定义值,其中该内存位置不是特定目标,并且在其他情况下具有现在将执行的其他目的!
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 theworst 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!
所以,最后,我们可以得到一个空指针错误,并且在检查指针时发现它包含一个空值;但是,找不到将空值放入指针或分配它的代码。这是空指针赋值错误的最广泛定义,绝对是空指针错误的最坏情况。在大型程序中发生这种情况时,通常会导致程序死亡,因为如果错误存在于以前的版本中,而是写入了以前可访问但未分配的非预期内存位置(允许程序运行或 IOW)在早期版本中,错误不会被注意到,直到程序被扩展,现在以前未使用的内存位置包含新代码或数据,这允许旧错误现在在新代码中生成随机错误或损坏数据!
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.
管理员和开发人员的逻辑通常规定,我为什么要查看那里,我们知道代码在最后几个版本中运行和工作得很好。但是,现在,部分新代码不起作用,主要部分已损坏。我们看又看,却什么也找不到。就好像错误不存在一样,但它确实存在。是什么原因造成的,谁怀疑多年前编写的代码?空指针和许多其他错误也是由此引起的。有了理解,以及一个可以直接检查代码的优秀编辑器,适当的监视器可以观察触发暂停的修改后的内存位置,以确定在正确的时间执行的代码,甚至可以找到。

