使用char指针和strcpy理解malloc
我想写一个简单的程序,我希望它不能理解strcpy和适当的内存管理,但它仍然执行。我正在尝试为一个字符串动态分配内存(使用malloc),该字符串只够用作目标的3个字符(或小于源字符的任何字符),并且分配的内存(或字符)少于堆栈上分配的源字符串数组(10个字符的字符串)。无论我如何定义内存分配,它都会复制和打印内容。这里怎么了使用char指针和strcpy理解malloc,c,pointers,malloc,strcpy,C,Pointers,Malloc,Strcpy,我想写一个简单的程序,我希望它不能理解strcpy和适当的内存管理,但它仍然执行。我正在尝试为一个字符串动态分配内存(使用malloc),该字符串只够用作目标的3个字符(或小于源字符的任何字符),并且分配的内存(或字符)少于堆栈上分配的源字符串数组(10个字符的字符串)。无论我如何定义内存分配,它都会复制和打印内容。这里怎么了 #include <stdio.h> #include <string.h> #include <stdlib.h> int mai
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *ch = NULL;
char name[10] = "something";
ch = (char*)malloc(3 * sizeof(char));
strcpy(ch, name);
printf("%s\n", name);
free(ch);
ch = NULL;
}
#包括
#包括
#包括
int main()
{
char*ch=NULL;
字符名[10]=“某物”;
ch=(char*)malloc(3*sizeof(char));
strcpy(ch,name);
printf(“%s\n”,名称);
免费(ch);
ch=NULL;
}
这里的错误是你所依赖的
编译器不会为超出限制(或无效)的内存访问抛出任何错误,但当您的程序尝试访问无效内存时,行为是未定义的
对于strcpy()
,如果目标缓冲区不够大,无法容纳来自源的内容,包括空终止符,那么实际上您将访问超出限制的内存,这是无效的,导致未定义的行为。程序员有责任确保目标缓冲区有足够的空间来存储要复制的字符串
从
strcpy()
函数将src
指向的字符串(包括终止的空字节('\0'
)复制到dest
指向的缓冲区。字符串不能重叠,目标字符串dest
必须足够大才能接收副本。[….]
将数组写出界的行为未定义。在我的计算机上,无需优化:
% gcc overflow.c
% ./a.out
something
并且启用了优化
% gcc -O3 overflow.c
In file included from /usr/include/string.h:495,
from overflow.c:2:
In function ‘strcpy’,
inlined from ‘main’ at overflow.c:10:5:
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:90:10: warning:
‘__builtin___memcpy_chk’ writing 10 bytes into a region of size 3
overflows the destination [-Wstringop-overflow=]
90 | return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
% ./a.out
*** buffer overflow detected ***: terminated
[2] 240741 abort (core dumped) ./a.out
原因是,通过优化,GCC将实际传播数组大小,并生成与
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
char name[10] = "something";
char *ch = malloc(3);
__memcpy_chk(ch, name, sizeof name, 3);
puts(name);
free(ch);
}
#包括
#包括
#包括
内部主(空)
{
字符名[10]=“某物”;
char*ch=malloc(3);
__memcpy_chk(ch,name,sizeof name,3);
(姓名);
免费(ch);
}
并且将检查目标缓冲区的长度,由于超出了该长度,程序将在运行时中止
始终在开发时,请记住测试您的代码是否也启用了优化 哦,我明白了。所以这段代码正在做我想要的事情,并且没有正确分配内存,但仍然在执行?@Onederfoo是的。未定义的bahaviour包括“显然工作正常”“我希望它不能理解strcpy和正确的内存管理,但它仍然执行“嗯…?”。。。?