我有一个文件,每行字符串都是这种格式
key1 = value1
key2 = value2
....
我需要在第三列中提取字符串。我到目前为止编写的代码是
fp = fopen(file, "r");
assert(fp && "checkpoint file not found \n");
char **data = (char **) malloc(sizeof (char*) * lines ); // lines=100
size_t i = 0;
while ((read = getline(&line, &len, fp)) != -1){
size_t l = strlen(line);
char value[256];
sscanf( line, "%s %s %s", field, tmp, value); // field stores 'key1', tmp stores '+', value stores 'value1'
data[i] = value;
i++;
printf("%s \n", value);
// printf("%s %s\n", value, data[i]); -- when this line is uncommented, it leads to a seg-fault.
}
fclose(fp);
for (int i=0; i < lines; ++i)
free(data[i]);
free(data);
我收到错误“对象的malloc错误..,未释放指针被释放”。
答案 0 :(得分:1)
我认为问题出在
之前 printf("%s %s\n", value, data[i]);
这一行,您正在i++
更改i
的值。然后data[i]
指向未初始化的内存。将其作为参数传递给%s
会导致undefined behavior。
[编辑:
然后,你正在做
free(data[i]);
然而,data[i]
不是内存分配器函数返回的指针。这是UB的另一个原因。
那就是说,
i
与lines
绑定,这是最大允许索引的一倍。您需要检查i < lines
始终满足。sscanf()
来电是否成功,此次通话失败也可能导致无效内存被读取。malloc()
and family in C
.。您还应该在取消引用返回的指针之前检查malloc()
是否成功。答案 1 :(得分:0)
观察到的错误的直接原因是:
char value[256];
//....
data[i] = value;
以及稍后(在后续循环中):
free(data[i]);
您正在释放静态分配的数组。
你想:
char *value=malloc(sizeof(char)*256);
我知道sizeof(char)==1
的定义。这只是一种很好的做法。
答案 2 :(得分:0)
声明char value[256]
在功能堆栈上保留一些空间。对于不同的data[i]
,您的i
会一直指向堆叠中的同一个位置。请注意,value
太小时,堆栈上可能存在溢出问题,除非其大小有固定限制。此堆栈区域未分配,因此无法释放,因此错误。
结果是data[i]
在第一次弃权后被所有其他行覆盖。每次都会获得一个指向同一区域的(不可释放的)指针。您需要将该值复制到tyour自己的指针:你还需要做的是在最后释放变量line
(因为它获得了一个malloc-ed指针值并被重新分配以使其适合该行。),并为每一行做{{{ 1}}创建指向 copy malloc
的指针并将value
设置为该新指针。所以你的代码中存在各种各样的问题。