释放 malloc 的内存会导致其他 malloc 的内存变成垃圾
freeing malloc'd memory causes other malloc'd memory to garbage
我正在尝试学习 C,我发现其中一件棘手的事情是字符串和操作它们。我想我了解它的基础知识,但我认为很多可能会进入 JS 或 PHP(我来自哪里)的字符串。
我现在正在尝试使用 strtok
编写一个基于定界符将字符串分解为数组的函数。类似于 PHP 对 explode()
的实现。
代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char **explode(char *input, char delimiter) {
char **output;
char *token;
char *string = malloc(sizeof(char) * strlen(input));
char delimiter_str[2] = {delimiter, '[=10=]'};
int i;
int delim_count = 0;
for (i = 0; i < strlen(input); i++) {
string[i] = input[i];
if (input[i] == delimiter) {
delim_count++;
}
}
string[strlen(input)] = '[=10=]';
output = malloc(sizeof(char *) * (delim_count + 1));
token = strtok(string, delimiter_str);
i = 0;
while (token != NULL) {
output[i] = token;
token = strtok(NULL, delimiter_str);
i++;
}
// if i uncomment this line, output gets all messed up
// free(string);
return output;
}
int main() {
char **row = explode("id,username,password", ',');
int i;
for (i = 0; i < 3; i++) {
printf("%s\n", row[i]);
}
free(row);
return 0;
}
我的问题是为什么如果我尝试在函数中 free(string)
,输出会变得混乱,如果我一开始就做错了。我相信我只是没有在脑海中正确地映射出记忆,这就是我不理解这个问题的原因。
在 output
中,您保存指向 string
的指针,因此当您释放 string
时,您释放了 output
指针指向的内存。
仅仅保存指针是不够的。您必须复制实际的字符串。为此,您需要以另一种方式将内存分配给 output
。
你误解了 strtok 的作用,它不会生成新字符串,它只是返回指向原始字符串不同部分的指针。如果您随后释放该字符串,则您存储的所有指针都将无效。我觉得你需要
while (token != NULL) {
output[i] = strdup(token);
token = strtok(NULL, delimiter_str);
i++;
}
strdup 将为您分配并复制一个新字符串
我正在尝试学习 C,我发现其中一件棘手的事情是字符串和操作它们。我想我了解它的基础知识,但我认为很多可能会进入 JS 或 PHP(我来自哪里)的字符串。
我现在正在尝试使用 strtok
编写一个基于定界符将字符串分解为数组的函数。类似于 PHP 对 explode()
的实现。
代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char **explode(char *input, char delimiter) {
char **output;
char *token;
char *string = malloc(sizeof(char) * strlen(input));
char delimiter_str[2] = {delimiter, '[=10=]'};
int i;
int delim_count = 0;
for (i = 0; i < strlen(input); i++) {
string[i] = input[i];
if (input[i] == delimiter) {
delim_count++;
}
}
string[strlen(input)] = '[=10=]';
output = malloc(sizeof(char *) * (delim_count + 1));
token = strtok(string, delimiter_str);
i = 0;
while (token != NULL) {
output[i] = token;
token = strtok(NULL, delimiter_str);
i++;
}
// if i uncomment this line, output gets all messed up
// free(string);
return output;
}
int main() {
char **row = explode("id,username,password", ',');
int i;
for (i = 0; i < 3; i++) {
printf("%s\n", row[i]);
}
free(row);
return 0;
}
我的问题是为什么如果我尝试在函数中 free(string)
,输出会变得混乱,如果我一开始就做错了。我相信我只是没有在脑海中正确地映射出记忆,这就是我不理解这个问题的原因。
在 output
中,您保存指向 string
的指针,因此当您释放 string
时,您释放了 output
指针指向的内存。
仅仅保存指针是不够的。您必须复制实际的字符串。为此,您需要以另一种方式将内存分配给 output
。
你误解了 strtok 的作用,它不会生成新字符串,它只是返回指向原始字符串不同部分的指针。如果您随后释放该字符串,则您存储的所有指针都将无效。我觉得你需要
while (token != NULL) {
output[i] = strdup(token);
token = strtok(NULL, delimiter_str);
i++;
}
strdup 将为您分配并复制一个新字符串