我有一个关于未定义变量的问题以及下面显示的剪切代码:
在func_1()
之后---它会将A
推入堆栈并将该内存的值设置为40,然后将A
弹出堆栈。
在func_2()
之后---它会再次将A
推入堆栈并继承之前设置的值,打印输出值将为40。
void func_1()
{ int A = 40;}
void func_2()
{ int A; printf("%d/n",A);}
void main (void)
{
func_1();
func_2();
}
如果我们将A
中的名称func_2()
更改为B
来测试堆栈的使用,并在其中加入额外的代码来测试命名变量池的使用: / p>
int A; printf("%d\n", A);
在我的计算机上,它显示B
为40,A
为0.
我想知道的是,如果编译器有一个命名变量池,它重用它来帮助它优化编译代码(?),那为什么我在A
得到0?
编译器何时使用池?
我的问题是基于这张幻灯片: http://www.slideshare.net/olvemaudal/deep-c/131-I_am_now_going_to
答案 0 :(得分:3)
函数A
中的变量func_2();
很可能被分配到保存值40
的相同堆栈位置(在func_1()
中)。因为,你没有初始化func_2()
中的变量,它将使用它在内存中的随机值打印变量40
(因为它从未被重写)。它类似于用户释放指针时的情况,并声称他们之后也能看到它的竞争,尽管他们可能会或不会看到它是未定义的行为。不用说,你不应该依赖这种行为!
我做了一个简单的测试,证明它与名字无关:
void func_1()
{
int A = 40;
int B = 10;
printf("Memory A = %p Memory B = %p\n",&A, &B);
}
void func_2()
{ int B; printf("B = %d Memory B = %p\n",B, &B);}
void main (void)
{
func_1();
func_2();
printf("\n");
}
<强>输出强>:
Memory A = 0x7fff58f86b5c Memory B = 0x7fff58f86b58
B = 40 Memory B = 0x7fff58f86b5c
正如您所看到的B = 10
func_1()
func_2()
中的A
打印值为40,为什么?如果检查func_1()
中变量B
的内存地址是0x7fff58f86b5c func_2()
中变量func loadContact(snap : FIRDataSnapshot) -> Contact {
let key = snap.key
let contact = (snap.value) as? NSDictionary
let c1 = Contact(
id: (contact?["id"] as? String)!,
firebasekey: key,
first_name: (contact?["First Name"] as? String)!,
middle_name: (contact?["Middle Name"] as? String)!,
last_name: (contact?["Last Name"] as? String)!,
suffix: (contact?["Suffix"] as? String)!,
company: (contact?["Company"] as? String)!,
phone_labe1: (contact?["Phone Label 1"] as? String)!,
phone1: (contact?["Phone 1"] as? String)!,
phone_label2: (contact?["Phone Label 2"] as? String)!,
phone2: (contact?["Phone 2"] as? String)!,
email_label1: (contact?["Email Label 1"] as? String)!,
email1: (contact?["Email 1"] as? String)!,
email_label2: (contact?["Email Label 2"] as? String)!,
email2: (contact?["Email 2"] as? String)!,
social: (contact?["Social Security Number"] as? String)!,
dob: (contact?["Date of Birth"] as? String)!,
street: (contact?["Street"] as? String)!,
city: (contact?["City"] as? String)!,
zip: (contact?["ZIP and Postal Code"] as? String)!,
state: (contact?["State and Province"] as? String)!,
reg_number: (contact?["Reg Num"] as? String)!,
stable_reg_number: (contact?["Stable Reg Num"] as? String)!,
emergency_contact: (contact?["Emergency Contact"] as? String)!,
emergency_phone: (contact?["Emergency Phone"] as? String)!,
drivers_license: (contact?["Driver's License Num"] as? String)!,
insurance_carrier: (contact?["Insurance Carrier"] as? String)!,
details: (contact?["Details"] as? String)!,
insurance_exp: (contact?["Insurance Expiration Date"] as? String)!,
insurance_group: (contact?["Insurance Group Num"] as? String)!,
insurance_member: (contact?["Insurnace Member Num"] as? String)!, // spelled wrong in database
job_title: (contact?["Job Title"] as? String)!,
date_modified: (contact?["Modified"] as? String)!,
keywords: [],
notes: []
)
return c1;
}
占用的内存地址相同。
答案 1 :(得分:3)
幻灯片中的人物扮演着一个发明一个想法的白痴,这个想法似乎解释了他不理解的行为。没有命名变量池。
此代码的行为未定义且无法依赖。如果它恰好在运行时表现为打印值40,那只是实现的意外。