>我对以下代码有两个问题:
#include <stdlib.h>
#include <stdio.h>
char *ft_strnew(size_t size)
{
char *result;
size_t i;
result = (char *) malloc(sizeof(char) * size);
if (result)
{
i = size;
while (i > 0)
{
result[i - 1] = ' ';
i = i - 1;
}
}
return (result);
}
int main(void)
{
char *test;
test = ft_strnew(1);
if (test)
{
test[2] = ' ';
test[1] = '1';
test[0] = '1';
printf("%s", test);
//free(&test);
}
return (0);
}
当我运行gcc -Wall -Werror -Wextra -o test ft_strnew.c && ./test
时,我得到:
11%
如果我取消注释包含main()
free()
调用的行,我会得到:
test(27744,0x7fff7941d300) malloc: *** error for object 0x7fff558b16d0: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
11zsh: abort ./test
1-为什么在第一种情况下没有段错误?
我创建的char *
的大小是 (1 * sizeof(char))
.但是我可以在其中添加三个字符('1', '1', ' ')
。
不应该是段错误吗?
2-为什么在第二种情况下存在免费问题?
即使我创建一个将 3 传递给 ft_strnew()
的char *
也会发生这种情况。我使用malloc()
调用创建char *
,不应该分配内存吗?
1-为什么在第一种情况下没有段错误?
它会导致未定义的行为,从而允许任何事情。该程序可能会按预期工作,它可能会出现段错误...什么。
2-为什么在第二种情况下存在免费问题?
您尝试释放指针的地址,而不是malloc
区域的地址。 free(test)
应该可以正常工作。
溢出从malloc()
返回的数组(或calloc()
或new
或任何其他类似的动态内存函数(并不总是导致任何失败的一个原因是因为 C 标准中的以下语句:
7.20.3 内存管理功能
。 如果分配成功,则返回的指针是合适的 对齐,以便可以将其分配给指向任何类型的对象的指针 然后用于访问此类对象或此类对象的数组 分配的空间。...
实际上,这意味着malloc()
将以离散块的形式返回内存,这些块与系统最严格的对齐要求相匹配。 例如,如果对象(如 double
或 long long
值(限制为 8 个字节的倍数,则此值可能是 8 个字节。 因此,如果您malloc()
1 个字节,您实际上会得到 8 个字节,并且可以"侥幸"使缓冲区溢出多达 7 个字节。 如果你malloc()
11 个字节,你实际上会得到 16 个字节。 但是,如果您malloc()
32 字节,您实际上会得到正好 32 个字节,并且根本无法"逃脱"溢出缓冲区。