为啥有些 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", &amp;n); 的内容或运行cmd.exe,转到包含可执行文件的目录并从那里运行它。

【讨论】:

以上是关于为啥有些 C 程序在 debug 中可以工作,但在 release 中不行?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的程序在发布模式下运行良好,但在调试模式下失败? [关闭]

为啥这段代码在 64 位架构上会出现段错误,但在 32 位上却能正常工作?

为啥 JDBC 代码在 Java 中可以工作,但在 Android 中返回 null?

我的应用程序在 iphone 5 中运行,但在 3 中无法运行,为啥? [关闭]

为啥这个 c++ 代码在 Linux 中可以正常工作,但在 Windows 中却不能[关闭]

为啥有些程序需要 .lib 和 .dll 才能工作