免费通话时出现故障

时间:2013-12-12 06:44:03

标签: c linux segmentation-fault free

char* meminfo()
{
char* buffer = NULL;
FILE* fp = fopen("/proc/meminfo", "r");
ssize_t read;

char* json = malloc(4096);
char* original = json;
json[0] = '\0';
json = strcat(json, "{");

size_t value = 1024;

while ( (read = getline(&buffer, &value, fp)) != -1)
{
    char name[1024];
    name[0] = '\0';

    char val[1024];
    val[0] = '\0';

    sscanf(buffer, "%s:", name);
    buffer = buffer + strlen(name);
    name[strlen(name) - 1] = '\0';

    sscanf(buffer, "%s kB", val);

    json = strcat(json, "\"");
    json = strcat(json, name);
    json = strcat(json, "\": \"");
    json = strcat(json, val);
    json = strcat(json, "\", ");
}
int n = strlen(json);
json[n - 2] = '}';
json[n - 1] = '\0';

fclose(fp);
return original;
}

所以我有这个函数读取并生成meminfo文件中数据的json字符串对象。但是,如果我在这个函数的返回值上调用free(),我会得到一个seg错误,我无法弄明白(我在函数中malloc变量并在之后释放它)。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您正在修改buffer连续调用getline()之间的位置。

buffer = buffer + strlen(name);

由于buffer指向的内存可能会在每次迭代过程中由getline()重新分配,因此不应在其间进行修改。

要解决此问题,请进行如下所示的备份:

char* meminfo()
{ 
    char * buffer = NULL;

    ...

    size_t value = 0;

    while ( (read = getline(&buffer, &value, fp)) != -1)
    {
      char * p = buffer; /* save the address, as buffer is modfied below. */

      ...

      buffer = p; /*restore address. */
    }

此外,代码错过了系统调用的错误检查。


另一个问题是,如果getline()没有返回任何内容,则此行会失败:

size_t n = strlen(json); 
/* json is "{" so its length would be 1 ... */

json[n - 2] = '}'; 
/* ... so here the code would address json[-1]. Which provokes undefinded behaviour. */