I realize the code sample below is something you should never do. My question is just one of interest. If you allocate a block of memory, and then move the pointer (a no-no), when you deallocate the memory, what is the size of the block that is deallocated, and where is it in memory? Here's the contrived code snippet:
我意识到下面的代码示例是你永远不应该做的事情。我的问题只是一个有趣的问题。如果你分配一块内存,然后移动指针(一个禁忌),当你释放内存时,解除分配的块的大小是多少,内存在哪里?这是人为的代码片段:
#include <stdio.h>
#include <string.h>
int main(void) {
char* s = malloc(1024);
strcpy(s, "Some string");
// Advance the pointer...
s += 5;
// Prints "string"
printf("%s\n", s);
/*
* What exactly are the beginning and end points of the memory
* block now being deallocated?
*/
free(s);
return 0;
}
Here is what I think I happens. The memory block being deallocated begins with the byte that holds the letter "s" in "string". The 5 bytes that held "Some " are now lost.
这就是我认为我发生的事情。被释放的内存块以保存字符串“s”的字节开头。持有“Some”的5个字节现在丢失了。
What I'm wondering is: Are the 5 bytes whose location in memory immediately follows the end of the original 1024 bytes deallocated as well, or are they just left alone?
我想知道的是:5个字节在内存中的位置是否紧跟原始1024字节的末尾分配,或者它们只是单独留下?
Anyone know for sure what is it the compiler does? Is it undefined?
任何人都知道编译器的作用是什么?这是不确定的?
Thanks.
11 个解决方案
#1
18
You cannot pass a pointer that was not obtained from a malloc
, calloc
or realloc
to free
(except NULL
).
您不能将未从malloc,calloc或realloc获取的指针传递给free(NULL除外)。
Question 7.19 in the C FAQ is relevant to your question.
C FAQ中的问题7.19与您的问题相关。
The consequences of invoking undefined behavior are explained here.
这里解释了调用未定义行为的后果。
#2
7
It's undefined behavior in the standard, so you can't rely on anything.
它是标准中未定义的行为,因此您不能依赖任何东西。
Remember that blocks are artificially delimited areas of memory, and don't automatically show up. Something has to keep track of the block, in order to free everything necessary and nothing more. There's no possible termination, like C strings, since there's no value or combination of values that can be guaranteed not to be inside the block.
请记住,块是人为分隔的内存区域,不会自动显示。有必要跟踪块,以释放所有必要的东西,仅此而已。没有可能的终止,比如C字符串,因为没有值或值的组合可以保证不在块内。
Last I looked, there were two basic implementation practices.
最后我看,有两个基本的实现实践。
One is to keep a separate record of allocated blocks, along with the address allocated. The free() function looks up the block to see what to free. In this case, it's likely to simply not find it, and may well just do nothing. Memory leak. There are, however, no guarantees.
一种是保留已分配块的单独记录以及分配的地址。 free()函数查找块以查看要释放的内容。在这种情况下,它可能根本找不到它,并且很可能什么都不做。内存泄漏。但是,没有任何保证。
One is to keep the block information in a part of memory just before the allocation address. In this case, free() is using part of the block as a block descriptor, and depending on what's stored there (which could be anything) it will free something. It could be an area that's too small, or an area that's too large. Heap corruption is very likely.
一种是在分配地址之前将块信息保存在存储器的一部分中。在这种情况下,free()使用块的一部分作为块描述符,并且根据存储的内容(可能是任何内容),它将释放一些东西。它可能是一个太小的区域,也可能是一个太大的区域。很可能是堆腐败。
So, I'd expect either a memory leak (nothing gets freed), or heap corruption (too much is marked free, and then reallocated).
因此,我预计内存泄漏(没有任何内容被释放)或堆损坏(太多标记为免费,然后重新分配)。
#3
5
Yes, it is undefined behavior. You're essentially freeing a pointer you didn't malloc
.
是的,它是未定义的行为。你基本上释放了一个没有malloc的指针。
#4
4
You cannot pass a pointer you did not obtain from malloc
(or calloc
or realloc
...) to free
. That includes offsets into blocks you did obtain from malloc
. Breaking this rule could result in anything happening. Usually this ends up being the worst imaginable possibility at the worst possible moment.
你不能将你没有从malloc(或calloc或realloc ...)获得的指针传递给free。这包括从malloc获得的块的偏移量。打破这个规则可能会导致任何事情发生。通常情况下,这最终可能是在最糟糕的时刻出现的最糟糕的可能性。
As a further note, if you wanted to truncate the block, there's a legal way to do this:
另外需要注意的是,如果要截断块,有一种合法的方法可以做到这一点:
#include <stdio.h>
#include <string.h>
int main() {
char *new_s;
char *s = malloc(1024);
strcpy(s, "Some string");
new_s = realloc(s, 5);
if (!new_s) {
printf("Out of memory! How did this happen when we were freeing memory? What a cruel world!\n");
abort();
}
s = new_s;
s[4] = 0; // put the null terminator back on
printf("%s\n", s); // prints Some
free(s);
return 0;
}
realloc
works both to enlarge and shrink memory blocks, but may (or may not) move the memory to do so.
realloc同时用于放大和缩小内存块,但可能(或可能不)移动内存来执行此操作。
#5
2
It is not the compiler that does it, it is the standard library. The behavior is undefined. The library knows that it allocated the original s
to you. The s+5
is not assigned to any memory block known by the library, even though it happens to be inside a known block. So, it won't work.
它不是编译器,它是标准库。行为未定义。图书馆知道它将原始文件分配给您。 s + 5未分配给库已知的任何内存块,即使它恰好位于已知块内。所以,它不会起作用。
#6
2
What I'm wondering is: Are the 5 bytes whose location in memory immediately follows the end of the original 1024 bytes deallocated as well, or are they just left alone?
我想知道的是:5个字节在内存中的位置是否紧跟原始1024字节的末尾分配,或者它们只是单独留下?
Both. The result is undefined so a compiler is free to do either of those, or anything else they'd like really. Of course (as with all cases of "undefined behavior") for a particular platform and compiler there is a specific answer, but any code that relies on such behavior is a bad idea.
都。结果是未定义的,因此编译器可以*地执行其中任何一个,或者他们真正喜欢的任何其他内容。当然(对于特定平台和编译器的所有“未定义行为”的情况),有一个特定的答案,但任何依赖于这种行为的代码都是一个坏主意。
#7
2
Calling free() on a ptr that wasnt allocated by malloc or its brethren is undefined.
在malloc或其兄弟未分配的ptr上调用free()是不确定的。
Most implementations of malloc allocate a small (typically 4byte) header region immediately before the ptr returned. Which means when you allocated 1024 bytes, malloc actually reserved 1028 bytes. When free( ptr ) is called, if ptr is not 0, it inspects the data at ptr - sizeof(header). Some allocators implement a sanity check, to make sure its a valid header, and which might detect a bad ptr, and assert or exit. If there is no sanity check, or it erroneously passes, free routine will act on whatever data happens to be in the header.
大多数malloc实现在ptr返回之前立即分配一个小的(通常是4byte)头区域。这意味着当你分配1024个字节时,malloc实际上保留了1028个字节。当调用free(ptr)时,如果ptr不为0,它将检查ptr-sizeof(header)中的数据。一些分配器实现了一个健全性检查,以确保它是一个有效的头,并可能检测到一个坏的ptr,并断言或退出。如果没有健全性检查,或者它错误地通过,则*例程将对标题中发生的任何数据起作用。
#8
1
Adding to the more formal answers: I'd compare the mechanics of this to one taking a book in the library (malloc), then tearing off a few dozen pages together with the cover (advance the pointer), and then attempting to return it (free).
添加到更正式的答案:我将这个机制与在图书馆(malloc)中拿一本书的机制进行比较,然后与封面一起撕下几十页(推进指针),然后尝试将其返回(*)。
You might find a librarian (malloc/free library implementation) that takes such a book back, but in a lot of case I'd expect you would pay a fine for negligent handling.
你可能会找到一本图书管理员(malloc /免费图书馆实施),它会把这本书拿回来,但在很多情况下,我希望你会因疏忽处理而支付罚金。
In the draft of C99 (I don't have the final C99 handy in front of me), there is something to say on this topic:
在C99的草案中(我没有最终的C99在我面前),在这个主题上有一些话要说:
The free function causes the space pointed to by
ptr
to be deallocated, that is, made available for further allocation. Ifptr
is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by thecalloc
,malloc
, orrealloc
function, or if the space has been deallocated by a call tofree
orrealloc
, the behaviour is undefined.free函数导致ptr指向的空间被释放,即可用于进一步分配。如果ptr是空指针,则不执行任何操作。否则,如果参数与之前由calloc,malloc或realloc函数返回的指针不匹配,或者如果通过调用free或realloc释放了空间,则行为未定义。
In my experience, a double free or the free of the "pointer" that was not returned via malloc
will result in a memory corruption and/or crash, depending on your malloc
implementation. The security people from both sides of the fence used this behaviour not once, in order to do various interesting things at least in early versions of the widely used Doug Lea's malloc
package.
根据我的经验,双重释放或没有通过malloc返回的“指针”将导致内存损坏和/或崩溃,具体取决于您的malloc实现。来自围栏两侧的安全人员不是一次使用这种行为,至少在广泛使用的Doug Lea的malloc包的早期版本中做了各种有趣的事情。
#9
0
The library implementation might put some data structure before the pointer it returns to you. Then in free()
it decrements the pointer to get at the data structure telling it how to place the memory back into the free pool. So the 5 bytes at the beginning of your string "Some " is interpreted as the end of the struct
used by the malloc()
algorithm. Perhaps the end of a 32 bit value, like the size of memory allocated, or a link in a linked list. It depends on the implementation. Whatever the details, it'll just crash your program. As Sinan points out, if you're lucky!
库实现可能会在返回给您的指针之前放置一些数据结构。然后在free()中,它递减指针以获取数据结构,告诉它如何将内存放回到空闲池中。因此,字符串“Some”开头的5个字节被解释为malloc()算法使用的结构的结尾。也许是32位值的结束,如分配的内存大小,或链接列表中的链接。这取决于实施。无论细节如何,它都会让你的程序崩溃。正如思南指出的那样,如果你幸运的话!
#10
0
Let's be smart here... free()
is not a black hole. At the very least, you have the CRT source code. Beyond that, you need the kernel source code.
让我们在这里很聪明... free()不是黑洞。至少,你有CRT源代码。除此之外,您还需要内核源代码。
Sure, the behavior is undefined in that it is up to the CRT/OS to decide what to do. But that doesn't prevent you from finding out what your platform actualy does.
当然,行为是不明确的,因为CRT / OS决定做什么。但这并不妨碍您了解您的平台实际上做了什么。
A quick look into the Windows CRT shows that free()
leads right to HeapFree()
using a CRT specific heap. Beoyond that you're into RtlHeapFree()
and then into system space (NTOSKRN.EXE) with the memory manager Mm*()
.
快速浏览一下Windows CRT,可以看出free()使用CRT特定堆直接进入HeapFree()。 Beoyond你进入RtlHeapFree()然后进入系统空间(NTOSKRN.EXE)与内存管理器Mm *()。
There are consistancey checks throughout all these code paths. But doing differnt things to the memory will cause differnt code paths. Hence the true definition of undefined.
在所有这些代码路径中都有一些检查。但是对内存执行不同的操作会导致不同的代码路径。因此undefined的真正定义。
At a quick glance, I can see that an allocated block of memory has a marker at the end. When the memory is freed, each byte is written over with a distinct byte. The runtime can do a check to see if the end of block marker was overwritten and raise an exception if so.
快速浏览一下,我可以看到分配的内存块最后有一个标记。释放存储器时,每个字节都用不同的字节写入。运行时可以检查块标记的结尾是否被覆盖,如果是,则引发异常。
This is a posiblility in your case of freeing memory a few bytes into your block (or over-writing your allocated size). Of course you can trick this and write the end of block marker yourself at the correct location. This will get you past the CRT check, but as the code-path goes futher, more undefined behavoir occurs. Three things can happen: 1) absolutely no harm, 2) memory corruption within the CRT heap, or 3) a thrown exception by any of the memory management functions.
在你的块中释放几个字节的内存(或者覆盖你分配的大小)的情况下,这是一种可行性。当然你可以欺骗它并在正确的位置自己编写块标记的结尾。这将使您通过CRT检查,但随着代码路径的进一步发展,将出现更多未定义的行为。可能会发生以下三种情况:1)完全没有危害,2)CRT堆内的内存损坏,或3)任何内存管理功能引发的异常。
#11
-2
Short version: It's undefined behavior.
简短版本:这是未定义的行为。
Long version: I checked the CWE site and found that, while it's a bad idea all around, nobody seemed to have a solid answer. Probably because it's undefined.
长版本:我检查了CWE网站,发现虽然周围都是一个坏主意,但似乎没有人有一个可靠的答案。可能是因为它未定义。
My guess is that most implementations, assuming they don't crash, would either free 1019 bytes (in your example), or else free 1024 and get a double free or similar on the last five. Just speaking theoretically for now, it depends on whether the malloc routine's internal storage tables contains an address and a length, or a start address and an end address.
我的猜测是,大多数实现,假设它们没有崩溃,将释放1019个字节(在您的示例中),或者释放1024并在后五个中获得双重释放或类似。从理论上说,现在,它取决于malloc例程的内部存储表是否包含地址和长度,或者起始地址和结束地址。
In any case, it's clearly not a good idea. :-)
无论如何,这显然不是一个好主意。 :-)
#1
18
You cannot pass a pointer that was not obtained from a malloc
, calloc
or realloc
to free
(except NULL
).
您不能将未从malloc,calloc或realloc获取的指针传递给free(NULL除外)。
Question 7.19 in the C FAQ is relevant to your question.
C FAQ中的问题7.19与您的问题相关。
The consequences of invoking undefined behavior are explained here.
这里解释了调用未定义行为的后果。
#2
7
It's undefined behavior in the standard, so you can't rely on anything.
它是标准中未定义的行为,因此您不能依赖任何东西。
Remember that blocks are artificially delimited areas of memory, and don't automatically show up. Something has to keep track of the block, in order to free everything necessary and nothing more. There's no possible termination, like C strings, since there's no value or combination of values that can be guaranteed not to be inside the block.
请记住,块是人为分隔的内存区域,不会自动显示。有必要跟踪块,以释放所有必要的东西,仅此而已。没有可能的终止,比如C字符串,因为没有值或值的组合可以保证不在块内。
Last I looked, there were two basic implementation practices.
最后我看,有两个基本的实现实践。
One is to keep a separate record of allocated blocks, along with the address allocated. The free() function looks up the block to see what to free. In this case, it's likely to simply not find it, and may well just do nothing. Memory leak. There are, however, no guarantees.
一种是保留已分配块的单独记录以及分配的地址。 free()函数查找块以查看要释放的内容。在这种情况下,它可能根本找不到它,并且很可能什么都不做。内存泄漏。但是,没有任何保证。
One is to keep the block information in a part of memory just before the allocation address. In this case, free() is using part of the block as a block descriptor, and depending on what's stored there (which could be anything) it will free something. It could be an area that's too small, or an area that's too large. Heap corruption is very likely.
一种是在分配地址之前将块信息保存在存储器的一部分中。在这种情况下,free()使用块的一部分作为块描述符,并且根据存储的内容(可能是任何内容),它将释放一些东西。它可能是一个太小的区域,也可能是一个太大的区域。很可能是堆腐败。
So, I'd expect either a memory leak (nothing gets freed), or heap corruption (too much is marked free, and then reallocated).
因此,我预计内存泄漏(没有任何内容被释放)或堆损坏(太多标记为免费,然后重新分配)。
#3
5
Yes, it is undefined behavior. You're essentially freeing a pointer you didn't malloc
.
是的,它是未定义的行为。你基本上释放了一个没有malloc的指针。
#4
4
You cannot pass a pointer you did not obtain from malloc
(or calloc
or realloc
...) to free
. That includes offsets into blocks you did obtain from malloc
. Breaking this rule could result in anything happening. Usually this ends up being the worst imaginable possibility at the worst possible moment.
你不能将你没有从malloc(或calloc或realloc ...)获得的指针传递给free。这包括从malloc获得的块的偏移量。打破这个规则可能会导致任何事情发生。通常情况下,这最终可能是在最糟糕的时刻出现的最糟糕的可能性。
As a further note, if you wanted to truncate the block, there's a legal way to do this:
另外需要注意的是,如果要截断块,有一种合法的方法可以做到这一点:
#include <stdio.h>
#include <string.h>
int main() {
char *new_s;
char *s = malloc(1024);
strcpy(s, "Some string");
new_s = realloc(s, 5);
if (!new_s) {
printf("Out of memory! How did this happen when we were freeing memory? What a cruel world!\n");
abort();
}
s = new_s;
s[4] = 0; // put the null terminator back on
printf("%s\n", s); // prints Some
free(s);
return 0;
}
realloc
works both to enlarge and shrink memory blocks, but may (or may not) move the memory to do so.
realloc同时用于放大和缩小内存块,但可能(或可能不)移动内存来执行此操作。
#5
2
It is not the compiler that does it, it is the standard library. The behavior is undefined. The library knows that it allocated the original s
to you. The s+5
is not assigned to any memory block known by the library, even though it happens to be inside a known block. So, it won't work.
它不是编译器,它是标准库。行为未定义。图书馆知道它将原始文件分配给您。 s + 5未分配给库已知的任何内存块,即使它恰好位于已知块内。所以,它不会起作用。
#6
2
What I'm wondering is: Are the 5 bytes whose location in memory immediately follows the end of the original 1024 bytes deallocated as well, or are they just left alone?
我想知道的是:5个字节在内存中的位置是否紧跟原始1024字节的末尾分配,或者它们只是单独留下?
Both. The result is undefined so a compiler is free to do either of those, or anything else they'd like really. Of course (as with all cases of "undefined behavior") for a particular platform and compiler there is a specific answer, but any code that relies on such behavior is a bad idea.
都。结果是未定义的,因此编译器可以*地执行其中任何一个,或者他们真正喜欢的任何其他内容。当然(对于特定平台和编译器的所有“未定义行为”的情况),有一个特定的答案,但任何依赖于这种行为的代码都是一个坏主意。
#7
2
Calling free() on a ptr that wasnt allocated by malloc or its brethren is undefined.
在malloc或其兄弟未分配的ptr上调用free()是不确定的。
Most implementations of malloc allocate a small (typically 4byte) header region immediately before the ptr returned. Which means when you allocated 1024 bytes, malloc actually reserved 1028 bytes. When free( ptr ) is called, if ptr is not 0, it inspects the data at ptr - sizeof(header). Some allocators implement a sanity check, to make sure its a valid header, and which might detect a bad ptr, and assert or exit. If there is no sanity check, or it erroneously passes, free routine will act on whatever data happens to be in the header.
大多数malloc实现在ptr返回之前立即分配一个小的(通常是4byte)头区域。这意味着当你分配1024个字节时,malloc实际上保留了1028个字节。当调用free(ptr)时,如果ptr不为0,它将检查ptr-sizeof(header)中的数据。一些分配器实现了一个健全性检查,以确保它是一个有效的头,并可能检测到一个坏的ptr,并断言或退出。如果没有健全性检查,或者它错误地通过,则*例程将对标题中发生的任何数据起作用。
#8
1
Adding to the more formal answers: I'd compare the mechanics of this to one taking a book in the library (malloc), then tearing off a few dozen pages together with the cover (advance the pointer), and then attempting to return it (free).
添加到更正式的答案:我将这个机制与在图书馆(malloc)中拿一本书的机制进行比较,然后与封面一起撕下几十页(推进指针),然后尝试将其返回(*)。
You might find a librarian (malloc/free library implementation) that takes such a book back, but in a lot of case I'd expect you would pay a fine for negligent handling.
你可能会找到一本图书管理员(malloc /免费图书馆实施),它会把这本书拿回来,但在很多情况下,我希望你会因疏忽处理而支付罚金。
In the draft of C99 (I don't have the final C99 handy in front of me), there is something to say on this topic:
在C99的草案中(我没有最终的C99在我面前),在这个主题上有一些话要说:
The free function causes the space pointed to by
ptr
to be deallocated, that is, made available for further allocation. Ifptr
is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by thecalloc
,malloc
, orrealloc
function, or if the space has been deallocated by a call tofree
orrealloc
, the behaviour is undefined.free函数导致ptr指向的空间被释放,即可用于进一步分配。如果ptr是空指针,则不执行任何操作。否则,如果参数与之前由calloc,malloc或realloc函数返回的指针不匹配,或者如果通过调用free或realloc释放了空间,则行为未定义。
In my experience, a double free or the free of the "pointer" that was not returned via malloc
will result in a memory corruption and/or crash, depending on your malloc
implementation. The security people from both sides of the fence used this behaviour not once, in order to do various interesting things at least in early versions of the widely used Doug Lea's malloc
package.
根据我的经验,双重释放或没有通过malloc返回的“指针”将导致内存损坏和/或崩溃,具体取决于您的malloc实现。来自围栏两侧的安全人员不是一次使用这种行为,至少在广泛使用的Doug Lea的malloc包的早期版本中做了各种有趣的事情。
#9
0
The library implementation might put some data structure before the pointer it returns to you. Then in free()
it decrements the pointer to get at the data structure telling it how to place the memory back into the free pool. So the 5 bytes at the beginning of your string "Some " is interpreted as the end of the struct
used by the malloc()
algorithm. Perhaps the end of a 32 bit value, like the size of memory allocated, or a link in a linked list. It depends on the implementation. Whatever the details, it'll just crash your program. As Sinan points out, if you're lucky!
库实现可能会在返回给您的指针之前放置一些数据结构。然后在free()中,它递减指针以获取数据结构,告诉它如何将内存放回到空闲池中。因此,字符串“Some”开头的5个字节被解释为malloc()算法使用的结构的结尾。也许是32位值的结束,如分配的内存大小,或链接列表中的链接。这取决于实施。无论细节如何,它都会让你的程序崩溃。正如思南指出的那样,如果你幸运的话!
#10
0
Let's be smart here... free()
is not a black hole. At the very least, you have the CRT source code. Beyond that, you need the kernel source code.
让我们在这里很聪明... free()不是黑洞。至少,你有CRT源代码。除此之外,您还需要内核源代码。
Sure, the behavior is undefined in that it is up to the CRT/OS to decide what to do. But that doesn't prevent you from finding out what your platform actualy does.
当然,行为是不明确的,因为CRT / OS决定做什么。但这并不妨碍您了解您的平台实际上做了什么。
A quick look into the Windows CRT shows that free()
leads right to HeapFree()
using a CRT specific heap. Beoyond that you're into RtlHeapFree()
and then into system space (NTOSKRN.EXE) with the memory manager Mm*()
.
快速浏览一下Windows CRT,可以看出free()使用CRT特定堆直接进入HeapFree()。 Beoyond你进入RtlHeapFree()然后进入系统空间(NTOSKRN.EXE)与内存管理器Mm *()。
There are consistancey checks throughout all these code paths. But doing differnt things to the memory will cause differnt code paths. Hence the true definition of undefined.
在所有这些代码路径中都有一些检查。但是对内存执行不同的操作会导致不同的代码路径。因此undefined的真正定义。
At a quick glance, I can see that an allocated block of memory has a marker at the end. When the memory is freed, each byte is written over with a distinct byte. The runtime can do a check to see if the end of block marker was overwritten and raise an exception if so.
快速浏览一下,我可以看到分配的内存块最后有一个标记。释放存储器时,每个字节都用不同的字节写入。运行时可以检查块标记的结尾是否被覆盖,如果是,则引发异常。
This is a posiblility in your case of freeing memory a few bytes into your block (or over-writing your allocated size). Of course you can trick this and write the end of block marker yourself at the correct location. This will get you past the CRT check, but as the code-path goes futher, more undefined behavoir occurs. Three things can happen: 1) absolutely no harm, 2) memory corruption within the CRT heap, or 3) a thrown exception by any of the memory management functions.
在你的块中释放几个字节的内存(或者覆盖你分配的大小)的情况下,这是一种可行性。当然你可以欺骗它并在正确的位置自己编写块标记的结尾。这将使您通过CRT检查,但随着代码路径的进一步发展,将出现更多未定义的行为。可能会发生以下三种情况:1)完全没有危害,2)CRT堆内的内存损坏,或3)任何内存管理功能引发的异常。
#11
-2
Short version: It's undefined behavior.
简短版本:这是未定义的行为。
Long version: I checked the CWE site and found that, while it's a bad idea all around, nobody seemed to have a solid answer. Probably because it's undefined.
长版本:我检查了CWE网站,发现虽然周围都是一个坏主意,但似乎没有人有一个可靠的答案。可能是因为它未定义。
My guess is that most implementations, assuming they don't crash, would either free 1019 bytes (in your example), or else free 1024 and get a double free or similar on the last five. Just speaking theoretically for now, it depends on whether the malloc routine's internal storage tables contains an address and a length, or a start address and an end address.
我的猜测是,大多数实现,假设它们没有崩溃,将释放1019个字节(在您的示例中),或者释放1024并在后五个中获得双重释放或类似。从理论上说,现在,它取决于malloc例程的内部存储表是否包含地址和长度,或者起始地址和结束地址。
In any case, it's clearly not a good idea. :-)
无论如何,这显然不是一个好主意。 :-)