运行 使用 malloc 进行内存管理
memory management using malloc while running
下面是我的C程序:
int main(int argc, const char *const *argv) {
char **upArgs = manipulate(argc, argv, toupper);
char **lowArgs = manipulate(argc, argv, tolower);
for (char *const *p = upArgs, *const *q = lowArgs; *p && *q; ++argv, ++p, ++q) {
printf("[%s] -> [%s] [%s]\n", *argv, *p, *q);
}
free_args(upArgs, lowArgs, NULL);
}
char **manipulate(int argc, const char *const *argv, int (*const change)(int)){
char **retArr = malloc((argc+1) * sizeof(char*));
for (int i = 0; i < argc; ++i) {
const char *const str = argv[i];
size_t len = strlen(str);
char* modified = malloc((len+1) * sizeof(char));
for (size_t j = 0; j < (len+1); ++j) {
modified[j] = change(str[j]);
}
retArr[i] = modified;
}
return retArr;
}
void free_args(char **args, ...){
va_list arg;
va_start(arg, args);
for(int i =0;i < **args; i++){
char *ar = va_arg(arg, char*);
free(ar);
}
va_end(arg);
}
当我 运行 "leaks -atExit -- ./test" 时没有内存泄漏。
但是当我 运行 "./test" 我得到以下错误。
malloc:对象 0x7f95324059c8 的 *** 错误:未分配正在释放的指针
我的内存分配哪里出错了?
**args
不是传递给 free_args
的参数数量。您正在使用 NULL
标记来指示参数的结尾,因此您应该检查一下。
此外,参数的类型是char**
,而不是char*
。
循环参数时,您需要从 args
开始,然后使用 va_arg
获取额外的参数。
void free_args(char **args, ...){
va_list arg;
va_start(arg, args);
for (char **ar = args; ar != NULL; ar = va_arg(arg, char**)) {
free(ar);
}
va_end(arg);
}
请注意,此 确实 存在内存泄漏。您正在释放 upArgs
和 lowArgs
数组,但没有释放它们指向的所有字符串。我没有展示如何解决这个问题,我认为这是故意的,以便 leak
报告问题。
当我使用
leaks --atExit -- ./testleaks a Bcd EF
我收到以下泄漏报告:
Process 30435: 8 leaks for 128 total leaked bytes.
8 (128 bytes) << TOTAL >>
1 (16 bytes) ROOT LEAK: 0x13f606880 [16]
1 (16 bytes) ROOT LEAK: 0x13f606890 [16]
1 (16 bytes) ROOT LEAK: 0x13f6068a0 [16]
1 (16 bytes) ROOT LEAK: 0x13f6068b0 [16]
1 (16 bytes) ROOT LEAK: 0x13f6068f0 [16]
1 (16 bytes) ROOT LEAK: 0x13f606900 [16]
1 (16 bytes) ROOT LEAK: 0x13f606910 [16]
1 (16 bytes) ROOT LEAK: 0x13f606920 [16]
下面是我的C程序:
int main(int argc, const char *const *argv) {
char **upArgs = manipulate(argc, argv, toupper);
char **lowArgs = manipulate(argc, argv, tolower);
for (char *const *p = upArgs, *const *q = lowArgs; *p && *q; ++argv, ++p, ++q) {
printf("[%s] -> [%s] [%s]\n", *argv, *p, *q);
}
free_args(upArgs, lowArgs, NULL);
}
char **manipulate(int argc, const char *const *argv, int (*const change)(int)){
char **retArr = malloc((argc+1) * sizeof(char*));
for (int i = 0; i < argc; ++i) {
const char *const str = argv[i];
size_t len = strlen(str);
char* modified = malloc((len+1) * sizeof(char));
for (size_t j = 0; j < (len+1); ++j) {
modified[j] = change(str[j]);
}
retArr[i] = modified;
}
return retArr;
}
void free_args(char **args, ...){
va_list arg;
va_start(arg, args);
for(int i =0;i < **args; i++){
char *ar = va_arg(arg, char*);
free(ar);
}
va_end(arg);
}
当我 运行 "leaks -atExit -- ./test" 时没有内存泄漏。
但是当我 运行 "./test" 我得到以下错误。
malloc:对象 0x7f95324059c8 的 *** 错误:未分配正在释放的指针
我的内存分配哪里出错了?
**args
不是传递给 free_args
的参数数量。您正在使用 NULL
标记来指示参数的结尾,因此您应该检查一下。
此外,参数的类型是char**
,而不是char*
。
循环参数时,您需要从 args
开始,然后使用 va_arg
获取额外的参数。
void free_args(char **args, ...){
va_list arg;
va_start(arg, args);
for (char **ar = args; ar != NULL; ar = va_arg(arg, char**)) {
free(ar);
}
va_end(arg);
}
请注意,此 确实 存在内存泄漏。您正在释放 upArgs
和 lowArgs
数组,但没有释放它们指向的所有字符串。我没有展示如何解决这个问题,我认为这是故意的,以便 leak
报告问题。
当我使用
leaks --atExit -- ./testleaks a Bcd EF
我收到以下泄漏报告:
Process 30435: 8 leaks for 128 total leaked bytes.
8 (128 bytes) << TOTAL >>
1 (16 bytes) ROOT LEAK: 0x13f606880 [16]
1 (16 bytes) ROOT LEAK: 0x13f606890 [16]
1 (16 bytes) ROOT LEAK: 0x13f6068a0 [16]
1 (16 bytes) ROOT LEAK: 0x13f6068b0 [16]
1 (16 bytes) ROOT LEAK: 0x13f6068f0 [16]
1 (16 bytes) ROOT LEAK: 0x13f606900 [16]
1 (16 bytes) ROOT LEAK: 0x13f606910 [16]
1 (16 bytes) ROOT LEAK: 0x13f606920 [16]