这两个错误将出现一个链表/低级文件读/ strtok程序.
==10982== Use of uninitialised value of size 4
==10982== at 0x40C3899: strtok (strtok.S:197)
==10982== by 0x8048719: main (main.c:9)
==10982== Uninitialised value was created by a stack allocation
==10982== at 0x80487D2: buildList (functions.c:13)
==10982==
==10982== Use of uninitialised value of size 4
==10982== at 0x40C38C1: strtok (strtok.S:223)
==10982== by 0x8048719: main (main.c:9)
==10982== Uninitialised value was created by a stack allocation
==10982== at 0x80487D2: buildList (functions.c:13)
==10982==
==10982== Conditional jump or move depends on uninitialised value(s)
==10982== at 0x40C38C4: strtok (strtok.S:224)
==10982== by 0x8048719: main (main.c:9)
==10982== Uninitialised value was created by a stack allocation
==10982== at 0x80487D2: buildList (functions.c:13)
Run Code Online (Sandbox Code Playgroud)
这是函数buildList
void buildList(int fdin, int lines)
{
char ara[4096];
int num;
double p;
read(fdin, ara, 4096);
char *nl = "\n";
char *ws = " ";
char *temp = strtok(ara, " ");
while(temp != NULL)
{
Stock *s = (Stock*)calloc(1, sizeof(Stock));
s->c.symbol = (char*)calloc(strlen(temp)+1, sizeof(char));
strcpy(s->c.symbol, temp);
temp = strtok(NULL, "\n");
s->c.name = (char*)calloc(strlen(temp)+1, sizeof(char));
strcpy(s->c.name, temp);
temp = strtok(NULL, "\n");
sscanf(temp, "%lf", &p);
temp = strtok(NULL, "\n");
s->price = p;
sscanf(temp, "%d", &num);
s->shares = num;
Node *n = (Node*)calloc(1, sizeof(Node));
n->data = s;
addOrdered(n);
temp = strtok(NULL, " ");
}
close(fdin);
}
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚为什么会出现这种错误.从我读到的内容是因为我正在从strtok向char*分配东西,而没有为它们分配任何内存.不过这就是我过去的做法,我认为一切都很好.
正如其他人所猜测的那样,valgrind抱怨strtok正在使用未初始化的内存。然后问题转向为什么,因为它似乎是通过以下方式初始化的:
read(fdin, ara, 4096);
Run Code Online (Sandbox Code Playgroud)
但是,read()不\0终止数据,而strtok期望\0终止的字符串。确保输入正确终止:
ssize_t result = read(fdin, ara, sizeof(ara)-1); /* leave room for '\0' */
ara[result > 0 ? result : 0] = '\0';
Run Code Online (Sandbox Code Playgroud)
memset(ara, 0, sizeof(ara));Lee Daniel Crocker的建议相当于相同类型的修复,但仅当文件包含少于sizeof(ara)字节的输入时才有效。如果您读取的文件有 4096 字节或更多的数据,您仍然会遇到类似的问题。然后,strtok将被迫扫描缓冲区的末尾以查找\0,从而导致未定义的行为。