在未使用的符号上获取 SEGFAULT
Getting a SEGFAULT on an unused symbol
我对 C 还是很陌生,所以如果我误解了一些基本的东西,请耐心等待
我有一个简单的程序,它应该将文件作为字符串读取,然后将该字符串拆分成行——将结果存储到 n 个字符串数组中。然而,当我 运行 以下代码时,我得到了一个 SEGFAULT - 使用 lldb 表明它是在 libsystem_platform.dylib 库中使用 strlen 时发生的,尽管我的代码中的任何地方都没有使用该函数。
这是完整的 FileIOTest.c 文件:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define ENDL "\n"
void read_file(const char* path, char** destination) {
FILE *file;
long size_in_bytes;
file = fopen(path, "r");
if(file == NULL) {
fputs("Requested file is invalid", stderr);
exit(-1);
}
fseek(file, 0L, SEEK_END);
size_in_bytes = ftell(file);
fseek(file, 0L, SEEK_SET);
fread(*destination, sizeof(char), size_in_bytes, file);
fclose(file);
}
int main() {
char* file = calloc(1024, sizeof(char));
read_file("run", &file);
char* destination[2048];
char* token = strtok(file, ENDL);
for(int i = 0; token != NULL; i++) {
destination[i] = token;
token = strtok(NULL, ENDL);
}
for(int i = 0; i < 2048; i++)
printf("%s", destination[i]);
}
我已验证文件读取有效 - 所以我的字符串拆分代码肯定有问题,但我看不出到底有什么问题
非常感谢任何帮助!
macOS Catalina 15.4 with lldb version lldb-1103.0.22.10 compiled with clang version clang-1103.0.32.62
您必须确保不超过目标大小。和 -1 表示空字符。
fread(*destination, sizeof(char), min(size_in_bytes, destinationSize - 1), file);
destination[i] 不以空字符结尾。您不能将它用作 printf
的参数
for(int i = 0; i < 2048; i++)
printf("%s", destination[i]); // can cause SEGFAULT
和另一个目的地限制检查。 i < 2048 应该添加到检查中。
for(int i = 0; token != NULL && i < 2048; i++) {
destination[i] = token;
token = strtok(NULL, ENDL);
}
事实证明,当您使用 %s 时,printf 在后台调用 strlen - 切换到 fputs 解决了这个问题
我对 C 还是很陌生,所以如果我误解了一些基本的东西,请耐心等待
我有一个简单的程序,它应该将文件作为字符串读取,然后将该字符串拆分成行——将结果存储到 n 个字符串数组中。然而,当我 运行 以下代码时,我得到了一个 SEGFAULT - 使用 lldb 表明它是在 libsystem_platform.dylib 库中使用 strlen 时发生的,尽管我的代码中的任何地方都没有使用该函数。
这是完整的 FileIOTest.c 文件:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define ENDL "\n"
void read_file(const char* path, char** destination) {
FILE *file;
long size_in_bytes;
file = fopen(path, "r");
if(file == NULL) {
fputs("Requested file is invalid", stderr);
exit(-1);
}
fseek(file, 0L, SEEK_END);
size_in_bytes = ftell(file);
fseek(file, 0L, SEEK_SET);
fread(*destination, sizeof(char), size_in_bytes, file);
fclose(file);
}
int main() {
char* file = calloc(1024, sizeof(char));
read_file("run", &file);
char* destination[2048];
char* token = strtok(file, ENDL);
for(int i = 0; token != NULL; i++) {
destination[i] = token;
token = strtok(NULL, ENDL);
}
for(int i = 0; i < 2048; i++)
printf("%s", destination[i]);
}
我已验证文件读取有效 - 所以我的字符串拆分代码肯定有问题,但我看不出到底有什么问题
非常感谢任何帮助!
macOS Catalina 15.4 with lldb version lldb-1103.0.22.10 compiled with clang version clang-1103.0.32.62
您必须确保不超过目标大小。和 -1 表示空字符。
fread(*destination, sizeof(char), min(size_in_bytes, destinationSize - 1), file);
destination[i] 不以空字符结尾。您不能将它用作 printf
的参数for(int i = 0; i < 2048; i++)
printf("%s", destination[i]); // can cause SEGFAULT
和另一个目的地限制检查。 i < 2048 应该添加到检查中。
for(int i = 0; token != NULL && i < 2048; i++) {
destination[i] = token;
token = strtok(NULL, ENDL);
}
事实证明,当您使用 %s 时,printf 在后台调用 strlen - 切换到 fputs 解决了这个问题