我声明一个字符串时保留了多少内存?

时间:2010-04-07 04:43:01

标签: c memory-management

在内存方面,当我宣布以下内容时会发生什么: char arr [4];

为arr保留了多少字节?

当我在arr中'strcpy'长度为4的字符串时,如何调整空字符串?

我正在编写套接字程序,当我尝试在arr [4](即第5个内存位置)处后缀NULL时,我最终替换了程序的其他一些变量的值(溢出)并进入了很大的时间。

有关编译器(gcc是我使用的)如何管理内存的任何描述?

5 个答案:

答案 0 :(得分:2)

sizeof(arr)个字节被保存*(加上编译器想要填充的任何填充,尽管这不是 数组本身)。在具有堆栈的实现上,这只意味着将堆栈指针sizeof(arr)字节向下移动。 (这就是存储的来源。这也是自动分配速度快的原因。)

'\0'不适用。如果你将“abcd”复制到其中,你会得到一个缓冲区溢出,因为它占用总共5个字节,但你只有4个。你输入了未定义的行为域,任何事情都可能发生。

实际上你会破坏堆栈并迟早崩溃,或者体验你所做的并覆盖附近的变量(因为它们也像数组一样被分配。)但是没有人可以肯定地说会发生什么,因为它是未定义。

*这是sizeof(char) * 4sizeof(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编译器的工作方式基本相同。