【问题标题】:Simple calloc and FILE code randomly crashes on windows简单的 calloc 和 FILE 代码在 Windows 上随机崩溃
【发布时间】:2017-01-13 22:10:25
【问题描述】:

我有一个代码应该生成一条用于监管目的的曲线,效果很好。

来自 Linux 环境,我真的不知道如何在 Windows 上编码(我必须在工作中使用它)所以我继续下载 Code::Blocks with MinGW

现在问题如下:我的代码可以工作,但有时会崩溃。我在 Linux 上尝试过,运行它没有任何问题,但是在 Windows 上,有时它会工作,有时它不会,告诉我这一点。

Problem signature:
  Problem Event Name:   APPCRASH
  Application Name: TabGen.exe
  Application Version:  0.0.0.0
  Application Timestamp:    02881c68
  Fault Module Name:    ntdll.dll
  Fault Module Version: 6.1.7601.23418
  Fault Module Timestamp:   5708a73e
  Exception Code:   c0000005
  Exception Offset: 00032a62
  OS Version:   6.1.7601.2.1.0.256.48
  Locale ID:    2055
  Additional Information 1: 0a9e
  Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
  Additional Information 3: 0a9e
  Additional Information 4: 0a9e372d3b4ad19135b953a78882e789

说实话,我不太明白。我尝试查找“异常代码 c0000005 窗口”,这显然意味着“访问冲突”,但我不明白它来自哪里,因为如前所述,它有时有效,有时却无效。

是否与 MinGW 相关?我的代码做错了吗?我有一个函数 mk_cp_table(它总是使用 4096 个值,这就是为什么它不是函数参数)但我很肯定它没问题。

另外,如果您想知道为什么我使用 calloc 而不是数组,那又是因为我不明白的错误。如果我将值放在数组中,则最后一个函数末尾的 fprintf 不起作用(但是单独使用 printf 显示它们效果很好,但 fprintf 只在我运行它时留下空白文件)。

有什么想法吗?

我的代码:

#include <stdio.h>
#include <stdlib.h>

void tab2file(FILE*, int, int*);
void mk_cp_table (int*, float, float, float, int, float, float, int);

int main (void)
{
    FILE* cp_file = fopen("cp_table.txt", "w");

    if (cp_file == NULL)
    {
        perror("failed fopen for cp_file\n");
        exit(EXIT_FAILURE);
    }

    int* cp_table = calloc((size_t) 4096, sizeof (int));

    if (cp_table == NULL)
    {
        fclose(cp_file);

        perror("failed calloc for cp_table\n");
        exit(EXIT_FAILURE);
    }

    /* Generate curves */

    mk_cp_table(
        cp_table,
        0.142,      /* scale */
        20,         /* zeroed distance 0 (negative part) */
        0.04,       /* slope 0 */
        120,        /* range 0 */
        20,         /* zeroed distance 1 (positive part) */
        0.04,       /* slope 1 */
        120         /* range 1 */
    );

    printf("\ntable generated\n");

    tab2file(cp_file, 4096, cp_table);

    printf("\ntables written to files\n");

    fclose(cp_file);
    free(cp_table);

    return EXIT_SUCCESS;
}

void tab2file(FILE* file, int size, int* table)
{
    int i;

    for (i = 0; i < size; i++)
        fprintf(file, "%d\n", table[i]);
}

void mk_cp_table(int* table, float scale, float zeroes_0, float slope_0, int range_0, float zeroes_1, float slope_1, int range_1)
{
    int i;
    int value;

    zeroes_0 = zeroes_0 / scale;
    zeroes_1 = zeroes_1 / scale;

    for (i = 0; i < 2048; i++)
    {
        if (i < zeroes_1)
            value = 0;

        else
            value = (i - zeroes_1) * slope_1;

        if (value > range_1)
            value = 127;

        table[i] = 0;
    }

    for (i = 0; i < 2048; i++)
    {
        if (i < zeroes_0)
            value = 0;
        else
            value = (zeroes_0 - i) * slope_0;

        if (value < -range_0)
            value = -127;

        table[4096 - i] = value;
    }
}

【问题讨论】:

  • table[4096 - i] = valuei==0 时,这写在table 的范围之外。
  • @Michael:那是心灵感应,我正要评论完全相同的事情!
  • @Luda Otaku 你写的越界,在你的程序的最后一行遇到一个相当于段错误的窗口。
  • 啊我想知道为什么我的手机一直在振动,很多cmets哈!
  • 谢谢你让我注意到这一点,我太专注于编写文件了。

标签: c windows file fopen calloc


【解决方案1】:

为了完整起见,所以这个问题不会留在未回答的部分中,您在 for 循环中程序的最后一行写出越界:

for (i = 0; i < 2048; i++)
{
    if (i < zeroes_0)
        value = 0;
    else
        value = (zeroes_0 - i) * slope_0;

    if (value < -range_0)
        value = -127;

    table[4096 - i] = value;    // out of bounds when i = 0.
}

这导致 windows 相当于 seg fault aka 访问冲突。如果你在 valgrind 下运行它,你也会在 unix 上注意到这一点。

【讨论】:

  • 同步!我同时发布了自己的答案。谢谢!
【解决方案2】:

事实证明这是一个分段错误,我有table[4096 - i] = value;,当 i 等于 0 时,它会超出数组的范围。

有时,当您过分关注您认为不起作用的代码部分时,您会忘记检查您认为有效的部分。

【讨论】:

    【解决方案3】:

    对于 4096 个元素的数组,4095 是您可以使用的最大有效索引。当i==0 时,语句table[4096 - i] = value; 写入table[4096],这超出了table 的范围。

    大概你打算做table[4095 - i] = value;,它会给你一个索引4095..2048。

    【讨论】:

      猜你喜欢
      • 2012-05-11
      • 1970-01-01
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-27
      • 1970-01-01
      相关资源
      最近更新 更多