我们说我有这样的事情:
char *array,*mat;
array= (char*)malloc(BUFFER * sizeof(char));
fscanf("%s",array);
mat = (char*)malloc(strlen(array) * sizeof(char));
strcpy(mat1, strarr1);
所以基本上,我会存储一些文本,然后将其复制,但如果原始文本小于BUFFER大小会发生什么?我的原始数组是否占用了我为其分配的大小,还是只占用了它所包含的字符串的大小?
答案 0 :(得分:4)
原始数组不会更改其大小。它占用您为其分配的确切大小。
存储在内存位置的数据只会覆盖以前在该位置写入的字节。
如果你分配了比你正在使用的空间更多的空间(对于你的字符串),那些额外的字节不被触及,它们保留了之前的相同数据。
如果您分配的空间少于您使用的空间,则会出现溢出。
答案 1 :(得分:2)
无论字符串有多长,数组array
都具有相同的大小。大小由malloc语句确定,之后不会更改。数组mat
与字符串一样长。
请记住为null分配一个额外的字符。
编码c(不是c ++)时,不要编译malloc。原因如下:Do I cast the result of malloc?
答案 2 :(得分:2)
当你为一个地址分配内存时,该内存会一直存在,并且可以重复使用,直到你释放它为止 例如:
char *buf1 = malloc(15);
strcpy(buf1, "15 characters."); //exactly 15 characters including NULL
|1|5| |c|h|a|r|a|c|t|e|r|s|.|\0|?|?|?|?|?|...
^ beginning and ^ end of allocated memory
如果您将内存分配给内存比第一个内存多的另一个缓冲区,并使用相同的内容对其进行初始化:
char *buf2 = malloc(20);
strcpy(buf2, "15 characters."); //exactly 15 characters including NULL
strcpy(buf1, buf2); //strcpy is successful, resulting memory is populated with:
|1|5| |c|h|a|r|a|c|t|e|r|s|.|\0|?|?|?|?|?|
但是,如果创建的buf2
内容少于buf1
,则buf1
的剩余内容将保留,但任何字符串函数都不会将其视为用于NULL终止符以确定字符串的结尾。例如:
char *buf2 = "short"; // contains 6 characters including NULL
strcpy(buf1, bu2); //strcpy is successful, and memory includes remnants old content
|s|h|o|r|t|\0|r|a|c|t|e|r|s|.|\0|?|?|?|?|?|
^^ end of new string, the rest is just artifact
警告:某些字符串函数(例如 strncpy )不会总是附加一个NULL字符:
如果,目的地末尾没有隐式附加空字符 来源长于num。
为了缓解这种情况,如果您需要将结果char数组视为C字符串,则必须始终为NULL字符包含足够的空间,并且在上述情况下,您必须在结尾处显式附加NULL char。缓冲。即,strncpy()
:
strncpy (target, source, n);
target[n] = 0;
使用分配的内存时,另一个有用的功能是 memset 。在多次操作中重复使用相同的缓冲区时,将内存中的所有位置重置为NULL是一个很好的做法:
memset(buf1, 0, 15);//results in...
|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|