这个代码显然存在问题,但它只会导致零售而不是调试中的访问冲突。任何具体原因? VS 2008是编译器。假设enabled = true
void parse(bool enabled)
{
char* p = NULL;
if (enabled)
{
char a[100] = 'jsajas';
p = &a;
}
if (p != NULL)
{
p[0] = 'a';
}
}
编辑:我知道失败的原因。我想知道是什么导致它在零售业中崩溃而不是在调试中崩溃。如何以不同的方式处理内存。
编辑:略微编辑代码,以便更清楚我的问题是什么。
编辑:恢复旧代码并在下面添加新代码,因为人们似乎不喜欢它。很抱歉引起混淆。我的目的是在堆中分配时真正理解该问题。
void parse(bool enabled)
{
char* p = NULL;
if (enabled)
{
char* a = new char[100];
a[0] = 'a';
p = a;
}
if (p != NULL)
{
p[0] = 'a';
}
}
答案 0 :(得分:3)
在控制流退出声明范围后,您正在访问变量(数组a
)。这是未定义的行为。
MSVC可以生成非常不同的代码,具体取决于您使用的是Release还是Debug。有可能:
为了找到答案,您可以查看生成的汇编代码。
答案 1 :(得分:2)
语句应该是p = a;
一个数组已经是一个指针,你告诉p是一个指针的指针,这就是你访问一些奇数内存位置的原因。在这个数组的顶部a是在一个范围内声明的,这是未定义的,一些编译器预先分配它并且它将正常工作,其他人只在if语句的范围内执行一次。
答案 2 :(得分:2)
应为char a[100] = "abcd"
(注意双引号)
应为p = a
或p = &a[0]
当然,只要a
超出第一个}
的范围,数组对象就不再有效。所以这是Undefined Behavior,它可以很容易地与一个编译器,编译器版本或一组开关一起工作,并与另一个开关崩溃。
答案 3 :(得分:1)
未定义未定义的行为。它可能会崩溃,垃圾堆栈,或只是正常进行。没有押韵或理由,因为它是 undefined 。它可以在不同的构建中做不同的事情;没有任何保证。因此,术语“未定义”。
这就是为什么你应该坚持使用定义的行为。
答案 4 :(得分:-1)
void parse(bool enabled)
{
char* p = NULL;
if (enabled)
{
char* a = new char[100];
a[0] = 'a';
p = a;
}
if (p != NULL)
{
p[0] = 'a';
}
}
您修改过的代码看起来不错。但是你没有释放从堆中分配的100个字节。指向分配的内存的指针(包括a和p)在此函数之外是未知的。这意味着此功能之外的任何人都无法解除分配。
内存泄漏。