简单的 calloc 和 FILE 代码在 windows 随机崩溃
Simple calloc and FILE code randomly crashes on windows
我有一个代码可以生成一条用于监管目的的曲线,效果很好。
来自 Linux 环境,我真的不知道如何在 Windows 上编码(我必须在工作中使用它)所以我继续下载 Code::Blocks 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
老实说,我不太明白。我试着查找 "Exception code c0000005 windows",这显然意味着 "access violation",但我不明白它的来源,因为正如所说,它有时有效,有时无效。
与 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;
}
}
为了完整起见,这个问题不会保留在未回答的部分,您在 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 等同于段错误,即访问冲突。如果你在 valgrind 下 运行 它,你也会在 unix 上注意到这一点。
事实证明这是一个分段错误,我有 table[4096 - i] = value;
当 i 等于 0 时它会超出数组的范围。
有时当您过于关注代码中您认为不起作用的部分时,您会忘记检查您认为有效的部分。
对于包含 4096 个元素的数组,4095 是您可以使用的最大有效索引。当 i
==0 超出 table
.
的范围时,语句 table[4096 - i] = value;
写入 table[4096]
大概你打算做 table[4095 - i] = value;
,这会给你一个索引 4095..2048.
我有一个代码可以生成一条用于监管目的的曲线,效果很好。
来自 Linux 环境,我真的不知道如何在 Windows 上编码(我必须在工作中使用它)所以我继续下载 Code::Blocks 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
老实说,我不太明白。我试着查找 "Exception code c0000005 windows",这显然意味着 "access violation",但我不明白它的来源,因为正如所说,它有时有效,有时无效。
与 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;
}
}
为了完整起见,这个问题不会保留在未回答的部分,您在 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 等同于段错误,即访问冲突。如果你在 valgrind 下 运行 它,你也会在 unix 上注意到这一点。
事实证明这是一个分段错误,我有 table[4096 - i] = value;
当 i 等于 0 时它会超出数组的范围。
有时当您过于关注代码中您认为不起作用的部分时,您会忘记检查您认为有效的部分。
对于包含 4096 个元素的数组,4095 是您可以使用的最大有效索引。当 i
==0 超出 table
.
table[4096 - i] = value;
写入 table[4096]
大概你打算做 table[4095 - i] = value;
,这会给你一个索引 4095..2048.