函数中 malloc 和 sscanf 引起的 seg 错误
我想打开一个文本文件(见下文),读取每行中的第一个 int 并将其存储在数组中,但出现分段错误。我摆脱了所有 gcc 警告,我阅读了在网上找到的几个教程并在 stackoverflow 中搜索解决方案,但我无法弄清楚我做错了什么。
当我在主函数中拥有所有内容时(请参见示例 1),它会起作用,但当我将其转移到第二个函数时(请参见下面的示例 2),它就不起作用了。在示例 2 中,当我正确解释 gdb 时,在 sscanf (line,"%i",classes[i]);
处出现段错误。
恐怕这可能是一件微不足道的事情,但我已经在上面浪费了一天的时间。
提前致谢。
[示例 1] 即使这适用于 main 中的所有内容:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const int LENGTH = 1024;
int main() {
char *filename="somedatafile.txt";
int *classes;
int lines;
FILE *pfile = NULL;
char line[LENGTH];
pfile=fopen(filename,"r");
int numlines=0;
char *p;
while(fgets(line,LENGTH,pfile)){
numlines++;
}
rewind(pfile);
classes=(int *)malloc(numlines*sizeof(int));
if(classes == NULL){
printf("\nMemory error.");
exit(1);
}
int i=0;
while(fgets(line,LENGTH,pfile)){
printf("\n");
p = strtok (line," ");
p = strtok (NULL, ", ");
sscanf (line,"%i",&classes[i]);
i++;
}
fclose(pfile);
return 1;
}
[示例 2] 这不适用于转移到函数的功能:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const int LENGTH = 1024;
void read_data(int **classes,int *lines, char *filename){
FILE *pfile = NULL;
char line[LENGTH];
pfile=fopen(filename,"r");
int numlines=0;
char *p;
while(fgets(line,LENGTH,pfile)){
numlines++;
}
rewind(pfile);
* classes=(int *)malloc(numlines*sizeof(int));
if(*classes == NULL){
printf("\nMemory error.");
exit(1);
}
int i=0;
while(fgets(line,LENGTH,pfile)){
printf("\n");
p = strtok (line," ");
p = strtok (NULL, ", ");
sscanf (line,"%i",classes[i]);
i++;
}
fclose(pfile);
*lines=numlines;
}
int main() {
char *filename="somedatafile.txt";
int *classes;
int lines;
read_data(&classes, &lines,filename) ;
for(int i=0;i<lines;i++){
printf("\nclasses[i]=%i",classes[i]);
}
return 1;
}
[某些数据文件的内容。 txt]
50 21 77 0 28 0 27 48 22 2
55 0 92 0 0 26 36 92 56 4
53 0 82 0 52 -5 29 30 2 1
37 0 76 0 28 18 40 48 8 1
37 0 79 0 34 -26 43 46 2 1
85 0 88 -4 6 1 3 83 80 5
56 0 81 0 -4 11 25 86 62 4
55 -1 95 -3 54 -4 40 41 2 1
53 8 77 0 28 0 23 48 24 4
37 0 101 -7 28 0 64 73 8 1
...
I want to open a text file (see below), read the first int in every line and store it in an array, but I get an segmentation fault. I got rid of all gcc warnings, I read through several tutorials I found on the net and searched stackoverflow for solutions, but I could't make out, what I am doing wrong.
It works when I have everything in the main function (see example 1), but not when I transfer it to second function (see example 2 further down). In example 2 I get, when I interpret gdb correctly a seg fault at sscanf (line,"%i",classes[i]);
.
I'm afraid, it could be something trivial, but I already wasted one day on it.
Thanks in advance.
[Example 1] Even though that works with everything in main:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const int LENGTH = 1024;
int main() {
char *filename="somedatafile.txt";
int *classes;
int lines;
FILE *pfile = NULL;
char line[LENGTH];
pfile=fopen(filename,"r");
int numlines=0;
char *p;
while(fgets(line,LENGTH,pfile)){
numlines++;
}
rewind(pfile);
classes=(int *)malloc(numlines*sizeof(int));
if(classes == NULL){
printf("\nMemory error.");
exit(1);
}
int i=0;
while(fgets(line,LENGTH,pfile)){
printf("\n");
p = strtok (line," ");
p = strtok (NULL, ", ");
sscanf (line,"%i",&classes[i]);
i++;
}
fclose(pfile);
return 1;
}
[Example 2] This does not with the functionality transfered to a function:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
const int LENGTH = 1024;
void read_data(int **classes,int *lines, char *filename){
FILE *pfile = NULL;
char line[LENGTH];
pfile=fopen(filename,"r");
int numlines=0;
char *p;
while(fgets(line,LENGTH,pfile)){
numlines++;
}
rewind(pfile);
* classes=(int *)malloc(numlines*sizeof(int));
if(*classes == NULL){
printf("\nMemory error.");
exit(1);
}
int i=0;
while(fgets(line,LENGTH,pfile)){
printf("\n");
p = strtok (line," ");
p = strtok (NULL, ", ");
sscanf (line,"%i",classes[i]);
i++;
}
fclose(pfile);
*lines=numlines;
}
int main() {
char *filename="somedatafile.txt";
int *classes;
int lines;
read_data(&classes, &lines,filename) ;
for(int i=0;i<lines;i++){
printf("\nclasses[i]=%i",classes[i]);
}
return 1;
}
[Content of somedatafile.txt]
50 21 77 0 28 0 27 48 22 2
55 0 92 0 0 26 36 92 56 4
53 0 82 0 52 -5 29 30 2 1
37 0 76 0 28 18 40 48 8 1
37 0 79 0 34 -26 43 46 2 1
85 0 88 -4 6 1 3 83 80 5
56 0 81 0 -4 11 25 86 62 4
55 -1 95 -3 54 -4 40 41 2 1
53 8 77 0 28 0 23 48 24 4
37 0 101 -7 28 0 64 73 8 1
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这:
可能是错误的。您也需要在那里取消引用,请尝试:
这是因为
classes
是指向整数数组的指针。您需要这些整数之一的地址,以便 sscanf() 可以在其中写入解析后的数字。因此,您必须首先取消引用classes
来获取数组,然后说出您想要该数组中元素号i
的地址。您还可以使用
“哪个可能更清晰”,具体取决于您对这些事情的适应程度。
This:
is probably wrong. You need to dereference there too, try:
This is because
classes
is a pointer to an array of integers. You want the address of one of those integers, so thatsscanf()
can write the parsed number there. Therefore, you must first dereferenceclasses
to get the array, then say that you want the address of element numberi
in that array.You could also use
Which might be clearer, depending on how comfortable you are with these things.
问题是您将 [] 运算符应用于第一种情况下的 int* 和第二种情况下的 int** 。 int** 就像一个二维数组,当您将 [] 运算符与 int** 结合使用时,您将索引到 int* 数组中。在您的情况下,这不是您想要的,因为您只初始化该数组中的第一个条目。因此,当您访问类[1]时,它会崩溃,因为它尚未初始化。您可以通过传入指针作为引用而不是双指针来避免这种混乱:
然后您可以使用与 main 函数中相同的代码。
The problem is you're applying the [] operator to an int* in the first case and an int** in the second. The int** is like a 2d array, when you use the [] operator in conjunction with the int** you are indexing into an array of int*. In your case this is not what you want, because you only initialize the first the first entry in this array. So when you access classes[1] it will crash because it's uninitialized. You could avoid yourself this confusion by passing in the pointer as a reference instead of a double pointer:
Then you could use the same code as from your main function.