我写了下面的c代码。
#include <stdio.h>
#include <stdlib.h>
char *read_from_file()
{
FILE *ptr_file;
char buf[22];
char buf_old[sizeof(buf)];
char candata_needed[4];
ptr_file =fopen("/home/pi/probe.txt","r");
if (!ptr_file){
fclose(ptr_file);
return 1;
}
if (fgets(buf,sizeof(buf), ptr_file)!=NULL){
if(memcmp(buf, buf_old, sizeof(buf)))
{
memcpy(candata_needed, buf + 17, sizeof(buf));
memcpy(buf_old, buf, sizeof(buf));
}
}
fclose(ptr_file);
return (candata_needed);
}
int main()
{
char *candata;
int i;
while(1){
printf("stape 1n");
candata=read_from_file()
for(i=0; i<4; i++)
{
candata[i] = *(candata + i);
}
printf("candata: %sn", candata);
}
free(candata);
return 0;
}
函数应该读取一个文件并将内容(内容是一个22十六进制数字)存储在一个数组中。从22十六进制数中,我只需要4,所以我将4十六进制数存储在一个数组中(candata_needed)。所以我想从一个主函数指针的函数中得到存储的4十六进制数。我尝试了malloc
,但我反复出现错误double free or corruption (fasttop)
。有了指针,什么也不会出现。有人能帮忙吗?
candata_needed
具有自动保存期限。当函数结束时,它将超出作用域。所以不要试图返回指向它的指针!
使用返回指针的行为是undefined。
一个解决方案是将字符缓冲区及其大小传递给read_from_file
。
返回一个指向局部数组的指针。一旦函数返回,这个局部数组就会超出作用域,给您留下一个指向不再存在的数组的指针。尝试使用该指针将导致未定义行为。
有几个解决方案:
-
将数组设置为全局变量
-
使数组为
static
。这意味着它的生命周期延长到程序的生命周期,并且指向它的指针在您返回它之后仍然有效。 -
使用
malloc
动态分配,并返回该指针。用完后别忘了free
内存 -
在调用函数中创建数组,并将指向该数组的指针作为参数传递。让函数填充这个数组。如果函数不知道大小(可能元素的数量),你也需要将其作为参数传递。
我个人推荐最后一种解决方案,但"最佳"可能因用例而异。我真的不建议推荐第一种解决方案,使其成为全局变量。我也不喜欢第二种,使变量成为static
变量,在我看来,这与拥有全局变量没有什么不同。
@Joachim Pileborg:我已经改变了我的代码,我现在使用malloc
:
#include <stdio.h>
#include <stdlib.h>
void read_from_file(char *result, int lenght_result)
{
FILE *ptr_file;
char buf[22];
char buf_old[sizeof(buf)];
char candata_needed[4];
//while(1){
ptr_file =fopen("/home/pi/probe.txt","r");
if (!ptr_file){
return 1;
}
if (fgets(buf,sizeof(buf), ptr_file)!=NULL){
if(memcmp(buf, buf_old, sizeof(buf)))
{
memcpy(candata_needed, buf + 17, sizeof(buf));
strncpy(result, candata_needed, lenght_result);
memcpy(buf_old, buf, sizeof(buf));
}
}
fclose(ptr_file);
}
int main()
{
int i;
int size=4;
char *candata = malloc(size);
while(1){
read_from_file(candata, size);
printf("candata: %sn", candata);
}
free(candata);
return 0;
代码工作,我可以得到数据。这样可以吗?还是不推荐?我的最终目标是将数据作为输出发送到另一个c程序。我是C语言的新手,很难找到解决这个问题的最佳方法。