[英]How to overcome Segfault on accessing pointer to array
我正在开发简单的 GTK3 C 应用程序(使用 WSL2 和 VSCode),但是当我尝试从文件中反序列化结构时,我遇到了段错误(我对 gdb 不是很熟悉,所以当我尝试调试时我真的不能找到导致错误的行)。
typedef struct whatev {
size_t id;
char* name;
int amount;
float value;
signed char state;
} SomeStruct;
Struct 是单独定义的,包括 header,在编译过程中不会引起任何问题(只是为了澄清)
SomeStruct* checkLine(char* str) {
char* readString;
int d1;
float f1;
sscanf(str, "%100[^;];%d;%f", readString, &d1, &f1);
// printf("Checking line: Read name: \"%s\", amount=%d, value=%f\n", readString, d1, f1);
if (readString[0] != '\0') {
SomeStruct* newLine = malloc(sizeof(SomeStruct));
// strcpy(newLine->name, readString);
newLine->name = readString;
newLine->amount = d1;
newLine->value = f1;
return newLine;
}
return NULL;
}
SomeStruct* createStructsFromFile(FILE* filestream, size_t fileLength) {
printf("Create struct from file: start\n");
SomeStruct* js = malloc(fileLength * sizeof(js));
SomeStruct* currentItem = malloc(sizeof(js));
size_t failed = 0;
size_t j = 0;
unsigned int buffer_size = 500;
// ERROR: Segfault somewhere here
for (size_t i = 0; i < fileLength; i++) {
char buffer[buffer_size];
fgets(buffer, buffer_size, filestream);
if ((currentItem = checkLine(buffer)) != NULL) {
currentItem->id = j;
currentItem->state = 0;
js[j] = *currentItem;
currentItem = (SomeStruct*)malloc(sizeof(js));
j++;
}
else
failed++; // TODO
}
printf("Create struct from file: Finished creating, failed reading %zd / %zd lines\n", failed, fileLength);
return js;
}
Breakpoint 5 at 0x80031a6: file FileOperations/fileOperations.c, line 125.
(gdb) step
[LWP 22523 exited]
createStructsFromFile: before assignment currentItem[0] (KsiążkaZPolskimiZnakami) to js[0]
123 js[j] = *currentItem;
(gdb) display js
13: js = (SomeStruct *) 0x85663e0
(gdb) display js[0]
14: js[0] = {id = 139820112, name = 0x0, amount = 137883733, value = 2.80259693e-44, state = 0 '\000'}
(gdb) display js[1]
15: js[1] = {id = 90194313216, name = 0xfffffff <error: Cannot access memory at address 0xfffffff>,
amount = 0, value = 0, state = 21 '\025'}
(gdb) display js[19]
16: js[19] = {id = 67174657, name = 0x0, amount = 0, value = -8.99305959e+35, state = 54 '6'}
(gdb) display currentItem
17: currentItem = (SomeStruct *) 0x83f34b0
(gdb) display currentItem->name
18: currentItem->name = 0x7ffffffecf30 "KsiążkaZPolskimiZnakami"
(gdb) step
Thread 1 "main" hit Breakpoint 5, createStructsFromFile (filestream=0x696b736c6f505a61,
fileLength=7763297035996459851) at FileOperations/fileOperations.c:125
125 printf("createStructsFromFile: inserted %zdth struct\n\n", j);
13: js = (SomeStruct *) 0x85663e0
14: js[0] = {id = 0, name = 0x7ffffffecf30 "KsiążkaZPolskimiZnakami", amount = 12,
value = 3.99000001, state = 0 '\000'}
15: js[1] = {id = 90194313216, name = 0xfffffff <error: Cannot access memory at address 0xfffffff>,
amount = 0, value = 0, state = 21 '\025'}
16: js[19] = {id = 67174657, name = 0x0, amount = 0, value = -8.99305959e+35, state = 54 '6'}
17: currentItem = (SomeStruct *) 0x83f34b0
18: currentItem->name = 0x7ffffffecf30 "KsiążkaZPolskimiZnakami"
(gdb) step
createStructsFromFile: inserted 0th struct
126 currentItem = malloc(sizeof(js));
13: js = (SomeStruct *) 0x85663e0
14: js[0] = {id = 0, name = 0x7ffffffecf30 "KsiążkaZPolskimiZnakami", amount = 12,
value = 3.99000001, state = 0 '\000'}
15: js[1] = {id = 90194313216, name = 0xfffffff <error: Cannot access memory at address 0xfffffff>,
amount = 0, value = 0, state = 21 '\025'}
16: js[19] = {id = 67174657, name = 0x0, amount = 0, value = -8.99305959e+35, state = 54 '6'}
17: currentItem = (SomeStruct *) 0x83f34b0
18: currentItem->name = 0x7ffffffecf30 "KsiążkaZPolskimiZnakami"
(gdb) step
start pętli 1
Thread 1 "main" received signal SIGSEGV, Segmentation fault.
0x00007ffffeae2657 in ?? ()
KsiążkaZPolskimiZnakami;12;3.99
Book with a lot of spaces;44;2.99
OutOfStock;0;1.00
LiterallyFreeNotebook;99;0.00
NextLineTriesToMakeScanfError;1;255.12
;;
HopeThatReadingWillWork;12;66.72
ThisBookHas7Parts;3;12.50
لكن لا بد أن أوضح لك أن كل هذه الأفكار;6;12.5
ArabicAndNeat;8;11
NegativeQuantity;-12;5.00
NegativeValue;7;-2.22
!LL3G4L_$|gNS;10;7.5
AboveWasJustSpace;2;0.1
TooManyArguments;1;15.55;12
UnexpectedType;3232.1;55
71830;80085;AndOtherFunnyThings
\0;\0;\0
EscapeSequence\n\"exit(1);11;255.1
YesILoveDebugging,Why?;-0;-99999999999999.9999
我想使用createStructsFromFile
的 output 填充 GTK TreeView。我也尝试使用双指针,但为了调试,我简化了返回( size_t createStructsFromFile(FILE* filestream, size_t fileLength, JakasStruktura** js)
哪里出了问题,我该如何改进?
如果需要,可以在我的 GitHub上找到代码
(提交)[https://github.com/ikarmus2001/ProjektC/commit/761a1f2000ee8ab1c32efd8449c1b95f8f11a2c1]
提前致谢
代码将未初始化的 object readString
传递给sscanf()
,导致未定义的行为(UB)。 @约翰尼莫普
char* readString;
...
sscanf(str, "%100[^;];%d;%f", readString, &d1, &f1); // bad
反而
char readString[100+1];
检查返回值
测试扫描是否成功**
// sscanf(str, "%100[^;];%d;%f", readString, &d1, &f1);
if (sscanf(str, "%100[^;];%d;%f", readString, &d1, &f1) != 3) {
Handle_bad_input();
}
需要字符串的副本
与其应对一个点,不如分配数据。
// newLine->name = readString;
newLine->name = malloc(strlen(readString) + 1);
if (newLine->name == NULL) {
TBD_eror_handling();
}
strcpy(newLine->name, readString);
较早的SomeStruct* newLine = malloc(sizeof(SomeStruct));
为结构分配了 memory,包括指针: .name
成员。 然而指针仍然没有指向任何分配的字符串。
稍后的代码需要在完成结构后释放此分配。
mallocking 结构是否已经为该指针保留了 memory? SomeStruct* newLine = malloc(sizeof(SomeStruct)); newLine->name = readString;
没有为结构本身分配空间。 所以你得到其中之一
typedef struct whatev {
size_t id;
char* name;
int amount;
float value;
signed char state;
} SomeStruct;
但是name
没有指向任何地方(malloc 甚至不知道那里有一个指针,它只是为您提供整个结构的原始 memory)。 您现在也需要在某处name
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.