为啥有些 C 程序在 debug 中可以工作,但在 release 中不行?
Posted
技术标签:
【中文标题】为啥有些 C 程序在 debug 中可以工作,但在 release 中不行?【英文标题】:Why do some C programs work in debug but not in release?为什么有些 C 程序在 debug 中可以工作,但在 release 中不行? 【发布时间】:2013-03-28 10:24:13 【问题描述】:好的,
所以我被困在这里。我有一个程序的代码,该程序根据算法系统地执行站成一圈的人,但我遇到了它在发布模式下崩溃的问题。如果我使用调试器(代码块)运行它,我的代码运行良好,但如果我不这样做,它就会崩溃。我在网上环顾四周,唯一发现的是未初始化的变量,但我尝试在声明时立即为变量设置值,但并没有解决问题。
如果有人能看到我的问题,我将不胜感激。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// if the program does not work, please run in debugger mode. It will work.
void remove_person(int** array, int arraySize, int position)
int i;
for (i = 0; i < arraySize; ++i)
printf("%d ", (*array)[i]);
printf("\n");
int* temp = malloc((arraySize - 1) * sizeof(int)); // create temporary array smaller by one element
memmove(temp,*array,(position+1)*sizeof(int)); // copy entire array before position
memmove(temp+position,(*array)+(position+1),(arraySize - position)*sizeof(int)); // copy entire array after postion
for (i = 0; i < arraySize - 1; ++i)
printf("%d ", (temp)[i]);
printf("\n");
free (*array);
*array = temp;
int kill(int** a, int n)
int pos = 0;
int round = 1;
while(n > 1)
pos = pos + 2 - (round % 2);
while(pos >= n)
pos = pos - n;
remove_person(a,n,pos);
n--;
while(pos >= n)
pos = pos - n;
round++;
return *a[0];
void main()
int n, survivor, i;
int* people;
printf("Enter number of people for Russian Roulette: \n");
scanf("%d", &n);
people = (int*) malloc(n*sizeof(int));
for(i=0; i < n; i++)
people[i] = i;
survivor = kill(&people, n);
printf("The survivor is person #%d\n", survivor);
【问题讨论】:
void main
是非标准的。
你不认为一个简单的列表会比这个解决方案漂亮吗?要从列表中删除元素,您只需 free()
它并修改前一个元素的 next
指针。
@chris:推荐阅读:homepage.ntlworld.com/jonathan.deboynepollard/FGA/…。 tl;dr:void main()
被 C99 标准以实现定义的方式允许。
@nneonneo,然后为this 感到羞耻。也许它专注于早期的标准。
@chris: Stroustrup 错了。阅读规范:c0x.coding-guidelines.com/5.1.2.2.1.html。注意“或等效的行;或以一些其他实现定义的方式。”
【参考方案1】:
标题问题(“为什么有些 C 程序在调试中工作而不在发布中工作?”)的基本答案是“当它们调用未定义的行为时”。
这里,在
memmove(temp,*array,(position+1)*sizeof(int)); // copy entire array before position
memmove(temp+position,(*array)+(position+1),(arraySize - position)*sizeof(int)); // copy entire array after postion
你抄的太多了。要了解原因,请观察第一个 memmove
复制到 temp[0]
、temp[1]
、...、temp[position]
,第二个复制到 temp[position]
、temp[position+1]
、...、temp[position+arraySize-position-1] = temp[arraySize-1]
(注意temp[position]
的重叠)。但是temp
只为arraySize-1
元素提供了空间——您复制的空间超出了允许的数量,因此您会得到未定义的行为。
它可能在调试模式下工作但在释放模式下工作,因为堆的布局不同(调试模式分配器可能会用额外的空间填充分配,以便在调试器或分析器下运行时捕获此类错误)。
【讨论】:
【参考方案2】:如果我输入 4(或大于 4 的数字)作为输入,程序会出现段错误,但我不会深入代码来了解为什么会发生这种情况。
除了程序运行良好之外,问题是您看不到输出,因为我认为您是在 Windows 上运行它。
话虽如此,您应该在末尾添加类似scanf("%d", &n);
的内容或运行cmd.exe
,转到包含可执行文件的目录并从那里运行它。
【讨论】:
以上是关于为啥有些 C 程序在 debug 中可以工作,但在 release 中不行?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我的程序在发布模式下运行良好,但在调试模式下失败? [关闭]
为啥这段代码在 64 位架构上会出现段错误,但在 32 位上却能正常工作?
为啥 JDBC 代码在 Java 中可以工作,但在 Android 中返回 null?
我的应用程序在 iphone 5 中运行,但在 3 中无法运行,为啥? [关闭]