问题描述
在 C 中有一个超级奇怪的问题,我认为它与字符串内存管理有关,但我已经仔细阅读了这段代码,但不知道我做错了什么。我正在设置一个指向字符串的指针数组,其中数组中的每个字符串都是一个从 strtok() 分解出来的标记,它在使用 stdin 由 getline 组成的一行上操作。
我已经能够分解标记、存储它们并毫无问题地打印数组。之后我只是在释放每个单独的指针时遇到了麻烦。我收到一条错误消息,指出“指针无效”,但奇怪的是,只有当我在原始字符串中输入奇数个单词时才会出现这种情况。即使我在字符串中输入奇数个单词,它仍然会将它们分解成标记并将它们存储在数组中,只是内存释放失败了。
这是我所拥有的片段:
char *line = NULL;
size_t len = 0;
getline(&line,&len,stdin);
char *token = strtok(line," \n");
char **parsed = malloc(sizeof(char*));
if(parsed == NULL){
printf("ruh roh scoob\n");
}
int numList = 0;
while(token!=NULL){
numList++;
parsed = realloc(parsed,sizeof(char*)*numList);
if(parsed == NULL){
printf("realloc Failed :(\n");
}
int tokenLen = strlen(token);
parsed[numList-1] = malloc(sizeof(char)*tokenLen);
if(parsed[numList-1] == NULL){
printf("ruh roh raggy\n");
}
strcpy(parsed[numList-1],token);
token = strtok(NULL," \n");
}
parsed[numList] = NULL;
for(int i = 0; i <= numList; i++){
printf("%d-%s",i,parsed[i]);
}
printf("\n");
for(int j = 0; j < numList; j++){
free(parsed[j]);
}
我以为我正在正确分配内存并将数据从我的令牌指针正确存储到新指针中,但也许我错了。任何建议将不胜感激!
解决方法
在你调用的循环内:
strcpy(parsed[numList-1],token);
这至少需要 strlen(token) + 1
个字节,但您分配的字节太少:
int tokenLen = strlen(token);
parsed[numList-1] = malloc(sizeof(char)*tokenLen);
因此 strcpy
写入缓冲区末尾,可能会随机破坏 malloc 元数据。请注意,您可能会在缓冲区结束后写入,因为 malloc
会将分配量向上舍入,以避免内存碎片并确保动态分配的缓冲区保持正确对齐(以获得更好的性能)。