我有一个链表并尝试将其中一个值分成两个不同的变量。我从包含"0000:c29302"
的id变量开始,但我想将":"
任意一侧的部分分解为clientid
和token变量。
当我运行我的代码时,它会在split函数中进入while循环,但之后只会出现崩溃。谢谢!
typedef struct node {
char *id;
char *clientid;
char *token;
struct node * next;
} credentials;
void split(credentials * head, char *delim);
int main()
{
credentials * head = NULL;
head = malloc(sizeof(credentials));
head->id = "0000:c29302";
head->next = NULL;
split(head, ":");
}
void split(credentials * head, char *delim)
{
char *token;
char *temp;
credentials * current = head;
while (current != NULL) { //THIS WHILE LOOP
temp = current->id;
token = strtok(temp, delim);
while(token != NULL)
{
printf("%s\n", token);
token = strtok(NULL, delim);
}
current = current->next;
}
}
答案 0 :(得分:4)
这种情况发生了,因为strtok()
修改了字符串参数!由于您在此处使用字符串文字,因此很可能将其保存在平台上的只读内存中。因此,每次尝试修改它都会导致违反分段"。
如果您确定您的字符串是可修改的,例如使用
head->id = strdup("0000:c29302");
它应该按预期工作!
答案 1 :(得分:1)
当您查看函数声明时:
char *strtok(char *str, const char *delim)
您可能会注意到delim
的类型为const char *
,但str
的类型为char *
。
这是因为此字符串str
的内容被修改并分解为更小的字符串(标记)。
"0000:c29302"
是一个字符串文字,其内容无法修改。
任何修改字符串文字的尝试通常都会导致运行时错误"Segmentation Violation".
您的strtok
必须指向可以修改的内存位置。
因此,您应该为其分配内存并将字符串文字复制到其中。
您可以使用malloc
:
head->id = malloc(strlen("0000:c29302")+1); // 1 char more for string terminator
strcpy(head->id, "0000:c29302");
或使用char * strdup(const char *str1);
返回指向以null结尾的字节字符串的指针,该字符串是str1
指向的字符串的副本。
head->id = strdup("0000:c29302");
在这两种情况下,必须在某个时刻释放字符串的已分配内存,以避免内存泄漏。