3

这样做有什么问题:

void *educator_func(void *param) {
char *lineE = (char *) malloc (1024);
size_t lenE = 1024;
ssize_t readE;

FILE * fpE;

fpE = fopen(file, "r");

if (fpE == NULL) {
    printf("ERROR: couldnt open file\n");
    exit(0);
}

while ((readE = getline(&lineE, &lenE, fpE)) != -1) {
    char *pch2E = (char *) malloc (50);

    pch2E = strtok(lineE, " ");

    free(pch2E);
}

free(lineE);
fclose(fpE);

return NULL;
}

如果我删除该行'pch2E = strtok(lineE, " ");'它工作正常...

为什么我不能在strtok()那里做?我也尝试过,strtok_r()但没有运气,它给了我无效的免费(地址 0x422af10 在大小为 1,024 的块内是 0 个字节)

4

2 回答 2

2

你的代码没有做你认为它正在做的事情......调用pch2E = strtok(lineE, " ");是用它pch2E的返回值替换值,strtok或者lineE是新分配的替换lineE

您可以按以下方式修复它...

int firstPass = 1;
while ((readE = getline(&lineE, &lenE, fpE)) != -1) 
{
    char* pch2E = strtok( firstPass ? lineE : NULL, " ");
    firstPass = 0;
}

free(lineE);

我应该补充一点,我越看你的代码,它在我看来就越有根本性的缺陷。您的代码中需要一个内部循环来处理标记,而外部循环正在加载行......

while ((readE = getline(&lineE, &lenE, fpE)) != -1) 
{
    char* pch2E;
    int firstPass = 1;

    while( (pch2E = strtok( firstPass ? lineE : NULL, " ")) != NULL )
    {
        firstPass = 0;
        // do something with the pch2E return value
    }
}

free(lineE);
于 2013-04-12T16:32:48.417 回答
1

strtok 返回一个指向令牌的指针,该指针包含在您传递的字符串中,因此您无法释放它,因为它不(总是)指向您使用 malloc 分配的内容。

这种分配甚至不能在 C 中工作,如果你想要一个将令牌复制到缓冲区的函数,它会是这样的:

tokenize(char* string, char* delimiter, char* token);

并且您需要将有效的指针传递给令牌,以便函数复制数据。在 C 中复制指针中的数据,函数需要访问该指针,因此函数不可能在返回值。

另一种策略(但最糟糕的)是在内部分配内存并返回指向需要由调用者释放的内存区域的指针的函数。

对于您的问题,需要多次调用 strtok 才能返回所有标记,直到它返回 null,所以它应该是:

while ((readE = getline(&lineE, &lenE, fpE)) != -1) {
    char *pch2E;

    pch2E = strtok(lineE, " "); //1st token

    while ((pch2E = strtok(NULL, " ")) != NULL) {
        //Do something with the token
    }
}
于 2013-04-12T16:44:51.247 回答