两个整数变量驻留在一个内存地址?

时间:2014-06-09 03:58:08

标签: c pointers memory

我正在学习C中的指针,并且正在尝试解决在线提供的指针练习。虽然下面的问题没有使用指针,但我知道错误的输出是由于缺少指针的使用。这是问题 -

/* p2.c 
Find out (add code to print out) the address of the variable x in foo1, and the 
variable y in foo2. What do you notice? Can you explain this? 
*/

这是我的答案 -

#include <stdio.h>
void foo1(int xval) 
{ 
 int x; 
 x = xval; 
 /* print the address and value of x here */ 
 printf("\n Address of variable x is:%p\n", &x);
 printf("\n Value of variable x is: %d\n", x); 

} 
void foo2(int dummy) 
{ 
 int y;
 y=dummy; 
 /* print the address and value of y here */ 
 printf("\n Address of variable y is:%p\n", &y);
 printf("\n Value of variable y is: %d\n", y); 
} 

int main() 
{ 
 foo1(7); 
 foo2(11); 

 return 0; 
} 

编译程序时的输出是 -

 Address of variable x is:0x7fff558fcb98

 Value of variable x is: 7

 Address of variable y is:0x7fff558fcb98

 Value of variable y is: 11

根据我的理解,当程序运行时,调用带有整数作为函数参数的foo1时,将获取整数7并将其存储在整数变量x中。函数foo1然后打印变量x的地址和值。同样的事情用函数foo2重复。

但是,我无法理解具有不同值的两个整数变量是如何驻留在同一个内存地址0x7fff558fcb98的?是因为C中的内存管理问题(mallocfree等 - 我还没有!)?

任何帮助都将受到高度赞赏。谢谢。

7 个答案:

答案 0 :(得分:4)

可视化堆栈的状态以了解行为。当你在主要时,让我们说堆栈看起来像:

enter image description here

当您输入foo1时,foo1的堆栈框架将添加到堆栈中,它看起来像:

enter image description here

foo1返回时,堆栈将恢复为:

enter image description here

当您输入foo2时,foo2的堆栈框架将添加到堆栈中,它看起来像:

enter image description here

对于foo1foo2,堆栈帧的状态看起来非常相似。局部变量xy的地址相同并不奇怪。

如果参数的数量,参数类型或局部变量类型不同,您会注意到局部变量地址的不同值。

答案 1 :(得分:3)

原因是这些变量位于调用堆栈中,并且相同的内存位置将重复用于后续调用。为了获得我认为你正在寻找的行为,在单个函数中声明两个变量并将输出语句放在它们旁边而不是放在另一个范围中。

答案 2 :(得分:1)

大多数编译器在函数内部在堆栈上分配局部变量

当函数返回时,内存返回到系统,另一个函数可以自由地将内存重用于另一个局部变量。

这里发生的事情就是foo1x分配内存,但是当它返回时,内存将返回系统,因为不再使用x

然后在foo2中重复使用相同的内存地址来存储y

请注意,堆栈上的内存不是使用malloc分配的,堆栈指针基本上只是一个在输入和退出函数时自动移动的指针。

答案 3 :(得分:0)

void foo1(int xval)void foo2(int dummy)是两个不同的函数,因此当一个函数运行时,只有该函数的变量驻留在堆栈中。一旦调用另一个函数或从函数返回,该函数的局部变量就会出现在堆栈中。因此,不同函数的两个变量可以具有相同的地址(但在不同的时间)。

答案 4 :(得分:0)

查看“静态”和“自动”内存分配之间的区别。您正在函数声明中使用自动内存分配,并在退出函数时释放内存:

当您声明自动变量(例如函数参数或局部变量)时,会发生自动分配。输入包含声明的复合语句时会分配自动变量的空间,并在退出该复合语句时释放。在GNU C中,自动存储的大小可以是变化的表达式。在其他C实现中,它必须是常量。

底线。在foo1(7)退出之后,在foo2(11)中,对于11,重用使用相同的内存。

答案 5 :(得分:0)

由于您现在必须阅读有关存储类的信息,请尝试将其与此相关联。这里的存储类是自动的。

主要 - &gt; foo1 - &gt;分配x - &gt;在foo1做的工作 - &gt;释放x - &gt;使用的内存位置调用foo2,然后重复y为x所做的事情(这里&#39; ll使用相同的内存位置,它没有x)。

这不是因为你没有使用指针。 您可能希望(您应该尝试)使用指针,如下所示,但再次期望相同的结果:

#include <stdio.h>
void foo1(int xval) 
{ 
 int *x; 
 x = &xval; 
 /* print the address and value of x here */ 
 printf("\n Address of variable pointed by x is:%p\n", x);
 printf("\n Value of variable x is: %d\n", *x); 

} 
void foo2(int dummy) 
{ 
 int *y;
 y=&dummy; 
 /* print the address and value of y here */ 
 printf("\n Address of variable y is:%p\n", y);
 printf("\n Value of variable y is: %d\n", *y); 
} 

int main() 
{ 
 foo1(7); 
 foo2(11); 

 return 0; 
} 

答案 6 :(得分:0)

你可能正在寻找这个:

 main()                                                           
   {
       char   a;                                                    
       int    x;                                                    
       float  p, q;                                                 

       a  = 'A';                                                    
       x  = 125;                                                    
       p  = 10.25, q = 18.76;                                       
       printf("%c is stored at addr %u.\n", a, &a);                 
       printf("%d is stored at addr %u.\n", x, &x);                 
       printf("%f is stored at addr %u.\n", p, &p);                
       printf("%f is stored at addr %u.\n", q, &q);                 

       }

// Declare and initialize an int variable

int var = 34;

// Declare a pointer to int variable

int *ptr;

// Initialize ptr to point to variable var

ptr = &var;



// Access var directly and indirectly

printf("\nDirect access, variable var value = var = %d", var);

// you can use %p for the pointer memory address directly or

// %0x or %0X or %p in hexadecimal representative instead of

// %d, just to avoid confusion here

printf("\nIndirect access, variable var value = *ptr = %d", *ptr);

// Display the address of var two ways

printf("\n\nThe memory address of variable var = &var = %p", &var);

printf("\nThe memory address of variable var = ptr = %p\n", ptr);