Jac*_*ack 3 c malloc memory-management
我对 malloc() 函数有点困惑。
如果sizeof(char)
是1 byte
并且malloc()
函数接受参数中的 N 个字节进行分配,那么如果我这样做:
char* buffer = malloc(3);
Run Code Online (Sandbox Code Playgroud)
我分配了一个可以存储3个字符的缓冲区,对吧?
char* s = malloc(3);
int i = 0;
while(i < 1024) { s[i] = 'b'; i++; }
s[i++] = '$';
s[i] = '\0';
printf("%s\n",s);
Run Code Online (Sandbox Code Playgroud)
效果很好。并将 1024 存储b's
在s
.
bbbb[...]$
Run Code Online (Sandbox Code Playgroud)
为什么上面的代码不会导致缓冲区溢出?谁能解释一下吗?
malloc(size)
size
返回内存中至少有字节可供您使用的位置。您可能能够立即写入 后的字节s[size]
,但是:
malloc()
或者,它们可能属于用于跟踪程序所使用内容的结构。破坏这个是非常糟糕的!s[size + large_number]
很难说哪一种会发生,因为访问您请求的空间之外malloc()
将导致未定义的行为。
在您的示例中,您溢出了 buffer,但不会导致立即崩溃。请记住,C 对数组/指针访问不进行边界检查。
另外,malloc()
在堆上创建内存,但缓冲区溢出通常与堆栈上的内存有关。如果您想创建一个作为练习,请使用
char s[3];
Run Code Online (Sandbox Code Playgroud)
反而。这将在堆栈上创建一个包含 3 个字符的数组。在大多数系统上,数组后面不会有任何可用空间,因此后面的空间s[2]
将属于堆栈。写入该空间可能会覆盖堆栈上的其他变量,并最终通过(例如)覆盖当前堆栈帧的返回指针而导致分段错误。
另一件事:
如果
sizeof(char)
是1字节
sizeof(char)
实际上标准定义为始终为 1 字节。然而,在外来系统上,1 个字节的大小可能不是 8 位。当然,大多数时候你不必担心这个。