访问在指向 strtok 的字符数组的指针中传递的变量时获取不正确的值

Getting incorrect values when accessing variables passed along in a pointer to a character array for strtok

这是我的代码

//Split up the config by lines
int x;
int numberOfConfigLines = 0;
for (x = 0; x < strlen(buffer); x++)
{
    if (buffer[x] == '\n') {
        numberOfConfigLines++;
    }
}
char *configLines[numberOfConfigLines];
tokenize(configLines, buffer, "\n", numberOfConfigLines);

这个函数的想法是计算缓冲区中换行符的数量,然后使用以下方法将缓冲区拆分为一个 strtok 数组:

#include <string.h>
#include <stdlib.h>

void tokenize(char **arrToStoreTokens, char *delimitedString, char *delimiter, int expectedTokenArraySize) {
    //Create a clone of the original string to prevent making permanent changes to it
    char *tempString = (char *)malloc(strlen(delimitedString) + 1);
    strcpy(tempString, delimitedString);

    if (expectedTokenArraySize >= 1) {
    arrToStoreTokens[0] = strtok(tempString, delimiter);

        int x;
        for (x = 1; x < expectedTokenArraySize; x++ ) {
            arrToStoreTokens[x] = strtok(NULL, delimiter);
        }
    }

    //Dispose of temporary clone
    free(tempString); 
}

如果我直接访问 arrToStoreTokens[0],我会得到正确的结果,但是当我尝试在 tokenize 函数结束后访问 configLines[0] 时,我会得到不同的结果(可以是未知字符或空)

此外,我相信这只是在我以 root 身份开始 运行 程序(针对不同的要求)后才开始发生 - 不过我可能错了。 -编辑:确认不是问题。

有什么想法吗?

strtok 不重新分配任何东西。它只对你给它的东西进行切割和指针。

您的数组存储 strtok 给您的指针,但不要复制内容。

因此,如果您释放 tempString 变量,则释放由 strtok 的 return 值指向的数据。你必须保留它并只在最后释放它。

或者您可以为 strtok 的每个 return 创建一个 strdup 以将其存储在您的数组中以制作每个令牌的真实副本,但在这种情况下,您必须释放每个标记在最后。

第二个解决方案如下所示:

void tokenize(char **arrToStoreTokens, char *delimitedString, char *delimiter, int expectedTokenArraySize) {
    //Create a clone of the original string to prevent making permanent changes to it
    char *tempString = (char *)malloc(strlen(delimitedString) + 1);
    strcpy(tempString, delimitedString);

    if (expectedTokenArraySize >= 1) {
    arrToStoreTokens[0] = strdup(strtok(tempString, delimiter)); // Here is the new part : strdup

        int x;
        for (x = 1; x < expectedTokenArraySize; x++ ) {
            arrToStoreTokens[x] = strdup(strtok(NULL, delimiter)); // Here is the new part : strdup
        }
    }

    //Dispose of temporary clone
    free(tempString); 
}

并且在使用这个数组之后,你必须删除它,函数如下:

void deleteTokens(char **arrToStoreTokens, int arraySize)
{
    int x;
    for (x = 0; x < arraySize; ++x)
    {
        free(arrToStoreTokens[x]);
    }
}