c语言中的字符串文字
我在c语言中的字符串文字,c,arrays,c-strings,C,Arrays,C Strings,我在C和字符数组方面遇到了一些问题。我试图继续搜索,但是我没有看到任何对我有帮助的东西,或者我没有找到合适的东西 我有一个函数: char* readFile(char* file_path) { FILE* fp = fopen(file_path, "r"); size_t buffer = 4096; char ch; int index = 0; char* line = (char*)malloc(sizeof(char) * buffer); while( (
C
和字符数组方面遇到了一些问题。我试图继续搜索,但是我没有看到任何对我有帮助的东西,或者我没有找到合适的东西
我有一个函数:
char* readFile(char* file_path)
{
FILE* fp = fopen(file_path, "r");
size_t buffer = 4096;
char ch;
int index = 0;
char* line = (char*)malloc(sizeof(char) * buffer);
while( (ch = (char)fgetc(fp)) != EOF )
{
line[index] = ch;
++index;
if(index == buffer -1)
{
buffer = buffer * 2;
line = realloc(line, buffer);
}
}
line = realloc(line, (sizeof(char) * index));
line[index] = '\0';
fclose(fp);
return line;
}
现在,当我在代码中使用这个函数并试图释放引用时,它会导致崩溃,所以我认为我在某处泄漏内存
char* data;
data = readFile("....");
free(data) <-- this line causes a crash!
所以完整的代码路径是这样的
char* vv = readFile("vshad.vs");
char* ff = readFile("fshad.fs");
sp = getShaderProgram(vv, ff);
free(vv);
free(ff);
我在空闲时(..)会崩溃,删除这些崩溃,程序运行正常,但我觉得这是内存泄漏。change
line=realloc(line,(sizeof(char)*index))代码>到
line = realloc(line, (sizeof(char) * (index+1)));
您正在尝试将行
重新定位到索引
大小,并在行[index]
中存储“\0”字符,这是未定义的行为。更改行=重新定位(行,(sizeof(char)*index))代码>到
line = realloc(line, (sizeof(char) * (index+1)));
您正在尝试将行
重新定位到索引
大小,并且下一个语句试图在行[index]
中存储'\0'字符,这是未定义的行为。为数组分配的内存不足。您刚刚为字符数组分配了内存,但没有为终止的\0
字符分配内存。这会导致未定义的行为
请更改以下行:
line = realloc(line, (sizeof(char) * index));
到
另外,将ch
的数据类型从char
更改为int,因为fgetc()
的返回类型是int
(而不是char
)。建议将返回值分配给整型变量
将值读入char
而不是int
时:
如果char是无符号的
,那么您将得到一个无限循环,因为我们永远不会得到EOF
如果字符是有符号的
,则0xFF
(即ÿ
被接受为EOF)被视为产生错误结果的EOF
此外,检查功能是否按预期工作:
- 检查文件打开是否成功。
FILE*fp=fopen(文件路径,“r”);
如果(fp!=NULL){
//做事
}
- 检查是否分配了内存
char* tmpLine = realloc(line, (sizeof(char) * (index+1)));
if (tmpLine != NULL)
{
line = tmp;
line[index] = '\0';
}
else
{
//Handle insufficient memory
}
为阵列分配的内存不足。您刚刚为字符数组分配了内存,但没有为终止的\0
字符分配内存。这会导致未定义的行为
请更改以下行:
line = realloc(line, (sizeof(char) * index));
到
另外,将ch
的数据类型从char
更改为int,因为fgetc()
的返回类型是int
(而不是char
)。建议将返回值分配给整型变量
将值读入char
而不是int
时:
如果char是无符号的
,那么您将得到一个无限循环,因为我们永远不会得到EOF
如果字符是有符号的
,则0xFF
(即ÿ
被接受为EOF)被视为产生错误结果的EOF
此外,检查功能是否按预期工作:
- 检查文件打开是否成功。
FILE*fp=fopen(文件路径,“r”);
如果(fp!=NULL){
//做事
}
- 检查是否分配了内存
char* tmpLine = realloc(line, (sizeof(char) * (index+1)));
if (tmpLine != NULL)
{
line = tmp;
line[index] = '\0';
}
else
{
//Handle insufficient memory
}
在C语言中,检查具有返回值的函数的返回值非常重要。在您的情况下,您使用realloc,但不必检查返回值
char* tmp = realloc(line, newbuffersize);
if (tmp != NULL)
{
line = tmp;
}
else
{
abort();
}
您应该检查文件是否正确打开,如果打开失败,并且在调用中开始使用空指针,您将得到有趣的行为
离开while循环后,使用新的realloc缩小缓冲区。这很好,但您需要为结尾添加空间\0:
char* tmp = realloc(line, index + 1);
if (tmp != NULL)
{
line = tmp;
line[index] = '\0';
}
一般来说,在执行分配时有点无效,如果先检查文件的大小(例如,先查看fseek到结尾,然后执行ftell,然后执行fseek到开始),然后分配相同大小的缓冲区(+1),则会更有效在阅读之前-如果你不是因为某种原因有严格的内存限制或一个大文件。在C语言中,检查具有返回值的函数的返回值是很重要的。在您的情况下,您使用realloc,但不必检查返回值
char* tmp = realloc(line, newbuffersize);
if (tmp != NULL)
{
line = tmp;
}
else
{
abort();
}
您应该检查文件是否正确打开,如果打开失败,并且在调用中开始使用空指针,您将得到有趣的行为
离开while循环后,使用新的realloc缩小缓冲区。这很好,但您需要为结尾添加空间\0:
char* tmp = realloc(line, index + 1);
if (tmp != NULL)
{
line = tmp;
line[index] = '\0';
}
一般来说,在执行分配时有点无效,如果先检查文件的大小(例如,先查看fseek到结尾,然后执行ftell,然后执行fseek到开始),然后分配相同大小的缓冲区(+1),则会更有效阅读前-如果不是因为某种原因,你有严格的内存限制或一个大文件。ch
应该是int
,而不是char
,因为这是fgets
的返回值,允许它区分常规输入和EOF
。收缩字符串时,应分配index+1
字节,额外的字节用于空终止符。您的最终realloc()
大小太小了一个。。。您需要index+1
字节,以便line[index]
仍在空字符的范围内。sizeof(char)
根据定义等于1
。所有这些强制转换都是无用的,而对于fgets()
的强制转换更是隐藏了一个严重的编程错误,正如M Oehm在这篇评论中指出的那样:如果内部控制数据被覆盖,则free
可能会崩溃。你在readFile
和“free”之间做什么?你考虑过在Valgrind这样的内存检查器中运行这个程序吗?@MOehm,谢谢,我会做出这些更改。我使用readFile函数来加载glsl