当我尝试使用 struct 运行 编程时出现分段错误(核心已转储)
I get segmentation fault (core dumped) when I tried to run program with struct
我需要读取文件并将文件中的数据存储到结构中。文件的第一行包含我必须动态分配的结构数组的大小。
4
12/04/2010
Interview went well I think, though was told to wear shoes.
18/04/2010
Doc advised me to concentrate on something... I forget.
03/05/2010
Was asked today if I was an art exhibit.
19/05/2010
Apparently mudcakes not made of mud, or angry wasps.
我 运行 我的代码在 Windows 中非常完美,但是当我在 Unix 环境中 运行 时它显示分段错误(核心转储)。我确实使用 valgrind
检查内存泄漏,这就是结果
==4344== Invalid read of size 1
==4344== at 0x407F842: ____strtol_l_internal (strtol_l.c:298)
==4344== by 0x407F606: strtol (strtol.c:108)
==4344== by 0x407C87E: atoi (atoi.c:27)
==4344== by 0x8048837: main (in /home/admininistrator/ucp/p6/gg)
==4344== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==4344==
==4344==
==4344== Process terminating with default action of signal 11 (SIGSEGV)
==4344== Access not within mapped region at address 0x0
==4344== at 0x407F842: ____strtol_l_internal (strtol_l.c:298)
==4344== by 0x407F606: strtol (strtol.c:108)
==4344== by 0x407C87E: atoi (atoi.c:27)
==4344== by 0x8048837: main (in /home/admininistrator/ucp/p6/gg)
==4344== If you believe this happened as a result of a stack
==4344== overflow in your program's main thread (unlikely but
==4344== possible), you can try to increase the size of the
==4344== main thread stack using the --main-stacksize= flag.
==4344== The main thread stack size used in this run was 8388608.
==4344==
==4344== HEAP SUMMARY:
==4344== in use at exit: 1,396 bytes in 3 blocks
==4344== total heap usage: 3 allocs, 0 frees, 1,396 bytes allocated
==4344==
==4344== LEAK SUMMARY:
==4344== definitely lost: 0 bytes in 0 blocks
==4344== indirectly lost: 0 bytes in 0 blocks
==4344== possibly lost: 0 bytes in 0 blocks
==4344== still reachable: 1,396 bytes in 3 blocks
==4344== suppressed: 0 bytes in 0 blocks
==4344== Rerun with --leak-check=full to see details of leaked memory
==4344==
==4344== For counts of detected and suppressed errors, rerun with: -v
==4344== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
附上我的代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"struct.h"
int main(int argc, char* argv[])
{
if (argc < 2)
{
printf("You have enter less arguments.\n");
}
else if (argc > 2)
{
printf("You have enter too many arguments.");
}
else
{
FILE *file;
Diary *res;
Diary *res2;
char line[102];
int i, size, k, l, choice;
int day, month, year;
/* int d[10],m[10],y[10];*/
char as[102];
char* oken;
char* yoken;
char* coken;
oken = NULL;
yoken = NULL;
coken = NULL;
i = 0;
file = fopen("struct.txt", "r");
if (file == NULL)
{
perror("Error opening file\n.");
}
else
{
fscanf(file, "%d", &size);
res = (Diary*) malloc(size * sizeof(Diary));
res2 = (Diary*) calloc((5), sizeof(Diary));
while (fgets(line, sizeof(line), file) != NULL)
{
oken = strtok(line, "/");
if (oken != NULL)
{
res2[i].day= atoi(oken);
coken = strtok(NULL, "/");
if (oken != NULL)
{
res2[i].month = atoi(coken);
yoken = strtok(NULL, "\n ");
if (coken != NULL)
{
/*printf("%s",yoken);*/
res2[i].year = atoi(yoken);
fgets(as, 102, file);
strncpy(res2[i].entry, as, 102);
}
}
}
i++;
}
k = 1;
l = 0;
while (l < size)
{
res[l].day = res2[k].day;
res[l].month = res2[k].month;
res[l].year = res2[k].year;
strncpy(res[l].entry, res2[k].entry, 102);
k++;
l++;
}
choice = atoi(argv[1]);
printf("%d-%02d-%02d:%s",res[choice].year, res[choice].month,res[choice].day,res[choice].entry);
free(res2);
free(res);
}
fclose(file);
}
return 0;
}
我需要将文件中的所有数据读取到结构中,并在用户需要条目时将其打印出来。我试着逐个调试,我发现它是 while( fgets( line, sizeof( line ), file) != NULL)
循环的部分,给出了问题。但我不知道如何解决它。
我的struct.h
如下:
typedef struct journal{
int day;
int month;
int year;
char entry[1024];
} Diary;
我不太了解您要实现的所有目标,但这里有一些问题。
- 您可能不需要
day month year
个变量。
这一行
day = atoi(oken);
应该是
res2[i].day = atoi(oken);
读取 size
的行有问题
fscanf(file, "%d", &size)
这会读取一个整数但不会读取尾随的换行符
您需要将其更改为
fscanf(file, "%d\n", &size)
或使用fgets
.
由于尾随换行符,下次调用 gets
时,您将获得一个仅包含换行符的字符串。
您的 strtok
调用和 NULL 检查不同步。第一个,对于 oken
是可以的。但是然后你做了一个 strtok
returning coken
但对 oken
进行了 NULL 检查,最后是 strtok
returning yoken
以及 coken
上的 NULL 检查。在所有 3 种情况下,调用 strtok
之后应该对 returned 值进行 NULL 检查(就像 oken
的情况一样)。
我不明白 while (l < size)
循环的目的(可能是因为如上所述对换行符的处理不当?)。您分配 5 个结构,从 structs.txt 读取 4 个到 res2
(元素 0 到 3),然后将 res2
的元素 1 到 4 复制到 res
的元素 0 到 3。这意味着 res2
的元素 0 不会被复制,而全为零的元素 4 会被复制。
崩溃的原因是第 3 点和第 4 点的组合。
我建议不要使用 atoi
,因为它不会进行错误检查。除非您确定该字符串包含格式正确的整数,否则使用它是不安全的。如果您希望代码健壮,则需要添加更多错误检查,例如,检查 malloc
和 calloc
.
的 return 值
我需要读取文件并将文件中的数据存储到结构中。文件的第一行包含我必须动态分配的结构数组的大小。
4
12/04/2010
Interview went well I think, though was told to wear shoes.
18/04/2010
Doc advised me to concentrate on something... I forget.
03/05/2010
Was asked today if I was an art exhibit.
19/05/2010
Apparently mudcakes not made of mud, or angry wasps.
我 运行 我的代码在 Windows 中非常完美,但是当我在 Unix 环境中 运行 时它显示分段错误(核心转储)。我确实使用 valgrind
检查内存泄漏,这就是结果
==4344== Invalid read of size 1
==4344== at 0x407F842: ____strtol_l_internal (strtol_l.c:298)
==4344== by 0x407F606: strtol (strtol.c:108)
==4344== by 0x407C87E: atoi (atoi.c:27)
==4344== by 0x8048837: main (in /home/admininistrator/ucp/p6/gg)
==4344== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==4344==
==4344==
==4344== Process terminating with default action of signal 11 (SIGSEGV)
==4344== Access not within mapped region at address 0x0
==4344== at 0x407F842: ____strtol_l_internal (strtol_l.c:298)
==4344== by 0x407F606: strtol (strtol.c:108)
==4344== by 0x407C87E: atoi (atoi.c:27)
==4344== by 0x8048837: main (in /home/admininistrator/ucp/p6/gg)
==4344== If you believe this happened as a result of a stack
==4344== overflow in your program's main thread (unlikely but
==4344== possible), you can try to increase the size of the
==4344== main thread stack using the --main-stacksize= flag.
==4344== The main thread stack size used in this run was 8388608.
==4344==
==4344== HEAP SUMMARY:
==4344== in use at exit: 1,396 bytes in 3 blocks
==4344== total heap usage: 3 allocs, 0 frees, 1,396 bytes allocated
==4344==
==4344== LEAK SUMMARY:
==4344== definitely lost: 0 bytes in 0 blocks
==4344== indirectly lost: 0 bytes in 0 blocks
==4344== possibly lost: 0 bytes in 0 blocks
==4344== still reachable: 1,396 bytes in 3 blocks
==4344== suppressed: 0 bytes in 0 blocks
==4344== Rerun with --leak-check=full to see details of leaked memory
==4344==
==4344== For counts of detected and suppressed errors, rerun with: -v
==4344== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)
附上我的代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"struct.h"
int main(int argc, char* argv[])
{
if (argc < 2)
{
printf("You have enter less arguments.\n");
}
else if (argc > 2)
{
printf("You have enter too many arguments.");
}
else
{
FILE *file;
Diary *res;
Diary *res2;
char line[102];
int i, size, k, l, choice;
int day, month, year;
/* int d[10],m[10],y[10];*/
char as[102];
char* oken;
char* yoken;
char* coken;
oken = NULL;
yoken = NULL;
coken = NULL;
i = 0;
file = fopen("struct.txt", "r");
if (file == NULL)
{
perror("Error opening file\n.");
}
else
{
fscanf(file, "%d", &size);
res = (Diary*) malloc(size * sizeof(Diary));
res2 = (Diary*) calloc((5), sizeof(Diary));
while (fgets(line, sizeof(line), file) != NULL)
{
oken = strtok(line, "/");
if (oken != NULL)
{
res2[i].day= atoi(oken);
coken = strtok(NULL, "/");
if (oken != NULL)
{
res2[i].month = atoi(coken);
yoken = strtok(NULL, "\n ");
if (coken != NULL)
{
/*printf("%s",yoken);*/
res2[i].year = atoi(yoken);
fgets(as, 102, file);
strncpy(res2[i].entry, as, 102);
}
}
}
i++;
}
k = 1;
l = 0;
while (l < size)
{
res[l].day = res2[k].day;
res[l].month = res2[k].month;
res[l].year = res2[k].year;
strncpy(res[l].entry, res2[k].entry, 102);
k++;
l++;
}
choice = atoi(argv[1]);
printf("%d-%02d-%02d:%s",res[choice].year, res[choice].month,res[choice].day,res[choice].entry);
free(res2);
free(res);
}
fclose(file);
}
return 0;
}
我需要将文件中的所有数据读取到结构中,并在用户需要条目时将其打印出来。我试着逐个调试,我发现它是 while( fgets( line, sizeof( line ), file) != NULL)
循环的部分,给出了问题。但我不知道如何解决它。
我的struct.h
如下:
typedef struct journal{
int day;
int month;
int year;
char entry[1024];
} Diary;
我不太了解您要实现的所有目标,但这里有一些问题。
- 您可能不需要
day month year
个变量。 这一行
day = atoi(oken);
应该是
res2[i].day = atoi(oken);
读取
的行有问题size
fscanf(file, "%d", &size)
这会读取一个整数但不会读取尾随的换行符
您需要将其更改为
fscanf(file, "%d\n", &size)
或使用
fgets
.由于尾随换行符,下次调用
gets
时,您将获得一个仅包含换行符的字符串。您的
strtok
调用和 NULL 检查不同步。第一个,对于oken
是可以的。但是然后你做了一个strtok
returningcoken
但对oken
进行了 NULL 检查,最后是strtok
returningyoken
以及coken
上的 NULL 检查。在所有 3 种情况下,调用strtok
之后应该对 returned 值进行 NULL 检查(就像oken
的情况一样)。我不明白
while (l < size)
循环的目的(可能是因为如上所述对换行符的处理不当?)。您分配 5 个结构,从 structs.txt 读取 4 个到res2
(元素 0 到 3),然后将res2
的元素 1 到 4 复制到res
的元素 0 到 3。这意味着res2
的元素 0 不会被复制,而全为零的元素 4 会被复制。
崩溃的原因是第 3 点和第 4 点的组合。
我建议不要使用 atoi
,因为它不会进行错误检查。除非您确定该字符串包含格式正确的整数,否则使用它是不安全的。如果您希望代码健壮,则需要添加更多错误检查,例如,检查 malloc
和 calloc
.