1
char* pointer;
char array[10];

我知道第二个内存已经分配在缓冲区中。但是,我不知道指针在内存分配方面的工作原理。在程序员使用 malloc 或 calloc 分配指针之前,指针最初占用多少空间?另外,如果我像这样初始化它

char* pointer;
pointer = "Hello World!";

如果在使用一些随机字符串大小初始化之前没有分配内存,那么这是如何初始化的?不会有任何错误吗?

我只是机械地使用指针和数组进行编程,而并不真正了解它在计算机内部的工作原理。而且,我认为我应该完全理解这一点,以便更好地进行编程练习。

4

7 回答 7

3

指针只是存储一个变量的地址。即,如果您说 char* 它存储一个字符的地址。像 int i=9; 表示 sizeof(int) 的内存被保留并在您的程序中标记为“i”。像明智的 char* c; 表示 size(char*) 的内存被保留并标记为“c”;在 c="你好"; "h","e","l","l","o" 分配了单独的“连续”内存。并且指针 c 指向第一个字符“H”。

考虑在内存中 HELLO 存储在字符串“India”之前。

“你好,印度。”

对于 char *c="HELLO"; c[5] 返回 I. for char c[5]="HELLO"; c[5] 是数组越界错误。

于 2013-03-11T05:51:47.043 回答
2

char array[10], 它将在您声明它的函数的堆栈帧上保留 10 个字节的内存。

而在char *ptr = "hello"ptr 中,将以4 bytes32 位的形式在堆栈上获取内存O.S"hello"而字符串文字也将存储在non-bss您的可执行文件的一部分中,并且 ptr 从堆栈帧中指向它。

于 2013-03-11T05:38:59.610 回答
1
  1. 本声明:

    char *pointer;
    

    为指针值保留sizeof(char *)字节。没有分配其他内存。

  2. 本声明:

    char array[10];
    

    为数组保留 10 个字节。

  3. 在这种情况下:

    char *pointer;
    pointer = "Hello World!";
    

    您仍然有一个指针(sizeof(char *)大小)指向内存中某处的字符串文字 - 没有其他分配发生。字符串文字的存储由您的工具链在编译时计算。

于 2013-03-11T05:27:46.357 回答
1

指针和数组是完全不同的东西。两者之间的任何相似和混淆都是 C 语言的产物。

指针是一个变量,它保存另一个变量的位置。数组(在 C 中)是相同类型的值的集合,在内存中连续分配。

数组通过算术访问指向基元素的指针,[0]. 如果对引用数组的表达式求值,则出现的值是指向 element 的指针[0]

int array[10];
int *p = array;     /* array expression yields pointer to array[0] */
int *q = &array[0]; /* q also points to same place as p */

C 中的数组表示法是一个假的,它实际上与指针一起工作。语法E1[E2]的含义与*(E1 + E2)(假设 E1 和 E2 有足够的括号,我们不必被关联性和优先级分心。)当我们通过 获取元素的地址时&E1[E2],这与&*(E1 + E2). 地址和取消引用“取消”离开E1 + E2。因此,这些也是等价的:

int *r = array + 3;
int *q = &array[3];

因为array[i]pointer[i]都是有效的语法,处于新手阶段的人(误认为语法是语义)得出的结论是数组和指针在某种程度上是同一回事。

花一些时间用汇编语言编程。在汇编语言中,您可能会定义一些像这样的存储:

 A: DFS 42          ;; define 42 words, labelled as A.

然后像这样使用它:

 MOV R13, A         ;; address of A storage is moved into R13
 MOV R1, [R13 + 3]  ;; load fourth word, A[3]

R13 指向存储。这并不意味着 A一个指针。A 是存储的名称。当然,要使用存储,我们需要它的有效地址,因此对 A 的引用可以解决这个问题。当代码被汇编和链接时,该MOV指令最终会将一些数字地址加载到 R13 中。

C 只是一种高级汇编语言。数组就像命名存储,它解析为其有效地址(作为指针数据类型)。

数组并不总是解析到它们的有效地址。sizeof a以字节为单位计算数组的大小a,而sizeof p计算指针数据类型的大小p

另一个区别是数组的名称不能引用该数组以外的任何地方,而我们可以为指针赋值:

array++;           /* invalid */
array = &array[0]; /* invalid */
p = &array2[0];    /* valid */
p++;               /* valid: point to the next element in array2 */
于 2013-03-11T05:51:29.640 回答
0

指针占用描述内存位置所需的任何空间。通常(但不总是),指针的大小与处理器/操作系统/程序模式的位大小相同(例如,64 位操作系统上的 64 位程序为 8 个字节,在 64 位操作系统上为 4 个字节32 位程序等)。您可以使用

sizeof (void *)

如果是

char* pointer;
pointer = "Hello World!";

您将在 R/W 内存中分配一个指针,加上 R/O 内存中的字符串空间(13 个字节,包括尾随的空字节),如果内存中的下一个对象对齐得比一个字节更好,则可能更多边界)。请注意,相同的 R/O 空间将被分配给

printf("Hello World!");

所以这实际上与指针无关。事实上,大多数优化编译器会注意到这两个字符串完全相同,并且只在 R/O 内存中分配一次。

于 2013-03-11T05:36:03.760 回答
0

我不知道指针在内存分配方面的工作原理。在程序员使用 malloc 或 calloc 分配指针之前,指针最初占用多少空间?

指针本身只是一种数据类型,如 int、char...等。它指向一个内存地址(或 NULL)。

它可以是 malloc,成为指向您要求的内存块的指针。

你很可能误认为指针 = malloc,它不是。

于 2013-03-11T05:36:39.190 回答
0

当您在 c 中定义指针时,例如 char *c; 或 int *i 它将分别保留等于 sizeof(char *) 和 sizeof(int *) 的内存。

但是实际保留的内存取决于您的系统/操作系统,如果是 64 位,则保留 8 个字节,如果是 32 位,则保留 4 个字节。

如果声明 char *c = "Hello world";

字符串“Hello world”可以存储在内存中的任何位置,但这里 c 指向字符串的第一个字符“H”。

于 2013-03-11T05:37:59.717 回答