指针和数组在内存方面的区别

时间:2013-03-11 05:24:14

标签: c memory

char* pointer;
char array[10];

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

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

如果在使用某个随机字符串大小初始化内存之前未分配内存,那么如何初始化内存?不会有任何错误吗?

我只是机械地使用指针和数组进行编程,而不知道它在计算机内是如何工作的。而且,我认为我应该理解这对于更好的编程实践。

7 个答案:

答案 0 :(得分:3)

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

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

“HELLOINDIA。”

表示char * c =“HELLO”; c [5]返回I. for char c [5] =“HELLO”; c [5]是数组超出范围的错误。

答案 1 :(得分:2)

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

然而在char *ptr = "hello"中,ptr将在32位4 bytes的堆栈中获得O.S内存,而"hello"也是字符串文字,将存储在non-bss部分你的可执行文件,ptr从堆栈框架指向它。

答案 2 :(得分:1)

  1. 此声明:

    char *pointer;
    

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

  2. 此声明:

    char array[10];
    

    为阵列保留10个字节。

  3. 在这种情况下:

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

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

答案 3 :(得分:1)

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

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

通过对基本元素[0]的指针的算术来访问数组。如果计算引用数组的表达式,则出现的值是指向元素[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 */

答案 4 :(得分:0)

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

找到它
sizeof (void *)

的情况下
char* pointer;
pointer = "Hello World!";

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

分配相同的R / O空间
printf("Hello World!");

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

答案 5 :(得分:0)

  

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

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

它可以是malloc,成为指向你问的内存块的指针。

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

答案 6 :(得分:0)

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

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

在声明char * c =“Hello world”的情况下;

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