在内存方面,当我宣布以下内容时会发生什么: char arr [4];
为arr保留了多少字节?
当我在arr中'strcpy'长度为4的字符串时,如何调整空字符串?
我正在编写套接字程序,当我尝试在arr [4](即第5个内存位置)处后缀NULL时,我最终替换了程序的其他一些变量的值(溢出)并进入了很大的时间。
有关编译器(gcc是我使用的)如何管理内存的任何描述?
答案 0 :(得分:2)
sizeof(arr)
个字节被保存*(加上编译器想要填充的任何填充,尽管这不是 数组本身)。在具有堆栈的实现上,这只意味着将堆栈指针sizeof(arr)
字节向下移动。 (这就是存储的来源。这也是自动分配速度快的原因。)
'\0'
不适用。如果你将“abcd”复制到其中,你会得到一个缓冲区溢出,因为它占用总共5个字节,但你只有4个。你输入了未定义的行为域,任何事情都可能发生。
实际上你会破坏堆栈并迟早崩溃,或者体验你所做的并覆盖附近的变量(因为它们也像数组一样被分配。)但是没有人可以肯定地说会发生什么,因为它是未定义。
*这是sizeof(char) * 4
。 sizeof(char)
总是 1,所以4个字节。
答案 1 :(得分:1)
在C中,你要求的是 - 通常 - 正是你得到的。 char arr[4]
正好是4个字节。
但引号中的任何内容都在末尾添加了“隐藏”null,因此char arr[] = "oops";
保留5个字节。
因此,如果你这样做:
char arr[4];
strcpy(arr, "oops");
...当你只为4保留空间时,你将复制5个字节(o o p s \0
)。接下来发生的任何事情都是不可预测的,而且往往是灾难性的。
答案 2 :(得分:1)
堆栈内存的究竟发生了什么 记忆,当我宣布像: char arr [4];
4 * sizeof(char)
个字节是为字符串保留的。
当我使用null字符串时如何 'strcpy'一个长度为4的字符串在arr?
你做不到。你只能有3个字符,第4个字符(即arr [3])应该是'\ 0'字符,用于正确的字符串。
当我在arr [4]
尝试后缀NULL时
当您访问无效的内存位置时,行为将是未定义的。在最好的情况下,您的程序会立即崩溃,但它可能会破坏堆栈并在以后的某个时间点崩溃。
答案 3 :(得分:0)
当您定义类似char arr[4]
的变量时,它会为该变量保留4个字节。正如你所发现的那样,超越这一点的写作会导致标准称之为“未定义的行为” - 对于“你搞砸了 - 不要那样做”的委婉说法。
这样的内存管理非常简单:如果它是全局的,它将在全局内存空间中分配。如果它是本地的,则通过从堆栈指针中减去适当的量来在堆栈上分配它。当你返回时,堆栈指针被恢复,所以它们不再存在(当你调用另一个函数时,通常会被该函数的参数和局部函数覆盖)。
答案 4 :(得分:0)
当您发出类似char arr[4];
的声明时,编译器会分配您要求的字节数,即四个。编译器可能分配额外的内容以便适应有效的内存访问,但通常你会得到你所要求的内容。
如果然后在同一个函数中声明另一个变量,那么该变量通常会跟随内存中的arr
,除非编译器再次进行某些优化。因此,如果您尝试写入arr
但写入的字符数超过实际为arr
分配的字符数,则可以覆盖堆栈中的其他变量。
这不是gcc的功能。所有C编译器的工作方式基本相同。