我试图通过编写自己的函数来模仿strcpy
的工作方式。我的问题更具体到数组的大小。
我正在尝试将stringA
的内容复制到stringB
,我已将其声明为1。
我不应该收到错误消息,指出stringB
太小而无法容纳stringA
吗?原因是,我怀疑我没有收到错误是因为数组名称StringB被转换为指针?
为什么char str[1] = "abcd"
非法?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void strCopy(char *source,char *destination) {
printf("%p,%p\n",source,destination);
while (*source != '\0') {
*destination = *source;
printf("> %c,%p,%p\n",*source,source,destination);
source++;
destination++;
}
*destination = '\0';
}
int main(int argc,char *argv[]) {
char stringA[] = "To be or not to be.";
char stringB[1];
strCopy(stringA,stringB);
printf("StringB: %s\n",stringB);
return (0);
}
答案 0 :(得分:2)
1)我不应该得到一个错误,说stringB太小而无法容纳stringA吗?
由于编译器内存分配方案,您没有收到任何错误。编译器很可能先将内存分配给stringB,然后再将stringA分配给stringA。因此,如果stringB具有内存位置1000(仅一个字节),则stringA将具有从1001到1020的内存位置(包括用于NULL的空间)。因此,当您尝试将内容从stringA复制到stringB到您的函数时,它实际上从位置1001复制到1000,然后从1002复制到1001,依此类推,所以根据您的程序,如果是这样的话,您必须输出如图所示。你似乎在打印字符串的地址。查看字符串的地址并检查是否是这种情况。再次,这仅仅是string2首先被分配内存而不是stringA的结果。在编译器的所有变体中,这都不是必要的,每次都是答案。
stringB:成为或不成为
stringA:o是或不是蜜蜂
现在你没有收到错误,因为两个数组都存在于堆栈帧中,并且两者都是通过指针访问的,所以编译器在使用指针完成数据复制时并不关心数组的大小。它只是复制,直到你在允许的内存空间。如果不是这种情况并且stringA首先出现在内存中,那么你会得到分段错误。
2)为什么char str [1] =&#34; abcd&#34;那么非法?
这不是一个非常不同的情况,你只分配一个字节到字符串,并用比其大小更多的字符初始化它。请注意,您的数据副本是在运行时完成的,但是这个初始化是在编译时,因此编译器知道数组的大小并会向您显示警告,这不是非法的,但编译器只将第一个字符分配给字符串,您可能会得到不可预测的结果是因为最后没有空格留给NULL字符。
答案 1 :(得分:1)
1)我不应该得到一个错误,说stringB太小而无法容纳stringA吗?
根据内存空间stringB
的位置,您可能不会收到错误。如果stringB
指针放在应用程序内存的中间,那么你当然可以写出超过其声明边界的值。你只需要覆盖用于存储其他值或功能的内存。 C / C ++永远不会像其他语言那样检查你是否超过了数组长度,例如: Java的。
2)为什么char str 1 =“abcd”非法呢?
由于程序的行为完全根据您的实现而未定义,因此很难准确描述正在发生的事情。
另请参阅以下帖子:why doesn't my program crash when I write past the end of an array?