C 字符数组、指针、malloc、自由
C char array, pointers, malloc, free
我正在尝试理解指针,我有这个简单的例子
void third(char ****msg) {
***msg = malloc(5 * sizeof (char));
printf("\nthe msg in third is :%s ", ***msg);
strcpy(***msg, "third");
printf("\nthe msg in third after is: %s", ***msg);
// free(***msg);
}
void change(char***msg) {
**msg = malloc(5 * sizeof (char));
printf("\nthe msg in change is :%s ", **msg);
strcpy(**msg, "change");
printf("\nthe msg in change after is: %s", **msg);
third(&msg);
// free(**msg);
}
void test(char ** msg) {
*msg = malloc(5 * sizeof (char));
printf("\n the msg in test is: %s", *msg);
strcpy(*msg, "test");
printf("\nthe msg in test after is: %s\n", *msg);
change(&msg);
free(*msg);
}
int main(int argc, char** argv) {
char * msg;
test(&msg);
printf("\nthe msg back in main is: %s", msg);
}
我可以说它工作正常,但是你能告诉我什么时候以及如何释放分配的内存吗,因为如果我从函数更改和第三个和 运行 中删除 // 我是有错误。有没有办法在每个函数的第一个 print 语句中获取消息的内容 - 请参阅 otuput:
the msg in test is:
the msg in test after is: test
the msg in change is :0��
the msg in change after is: change
the msg in third is :P��
the msg in third after is: third
the msg back in main is:
有没有办法让 msg 发生变化:测试然后
第三个消息是:更改
在现实生活中,尽量避免使用"star"(即间接数)。您的代码还有几个问题涉及 undefined behavior (UB)
void third(char ****msg) {
***msg = malloc(5 * sizeof (char));
printf("\nthe msg in third is :%s ", ***msg);// Don't do that, ***msg is not intialize => UB
strcpy(***msg, "third"); // Don't do that => ***msg has 5 bytes, and you copy 6 char => UB
printf("\nthe msg in third after is: %s", ***msg);
// free(***msg);
}
void change(char***msg) {
**msg = malloc(5 * sizeof (char));
printf("\nthe msg in change is :%s ", **msg);// Don't do that, **msg is not intialize => UB
strcpy(**msg, "change"); // Don't do that => **msg has 5 bytes, and you copy 7 char => UB
printf("\nthe msg in change after is: %s", **msg);
third(&msg);
// free(**msg);
}
void test(char ** msg) {
*msg = malloc(5 * sizeof (char));
printf("\n the msg in test is: %s", *msg); // Don't do that, *msg is not intialize => UB
strcpy(*msg, "test");
printf("\nthe msg in test after is: %s\n", *msg);
change(&msg);
free(*msg);
}
int main(int argc, char** argv) {
char * msg;
test(&msg);
printf("\nthe msg back in main is: %s", msg); //UB => you use freed variable
}
改正了这个UB的多个来源后,它仍然是一个糟糕的设计:使用free
函数
根据您使用...的指针这一事实,当您在函数内部执行 malloc
时,您还修改了调用者的指针。试试 运行 这个看看:
void first(char **t)
{
*t = malloc(5*sizeof(char));
}
int main(int argc, char * argv[])
{
char * t = NULL;
printf("%p\n", t);
first(&t);
printf("%p\n", t);
return 0;
}
它产生 (demo):
(nil)
0x995f008 (or another address)
因此,当您在 test
中释放时,您释放了在 third
中分配的内存
最后,评论里已经说了,2星就够了:
void third(char **msg) {
free(*msg); // Free before allocate and change address stored in pointer
*msg = malloc(6 * sizeof (char));
strcpy(*msg, "third");
printf("\nthe msg in third after is: %s", *msg);
}
void change(char **msg) {
free(*msg); // Free before allocate and change address stored in pointer
*msg = malloc(7 * sizeof (char));
strcpy(*msg, "change");
printf("\nthe msg in change after is: %s", *msg);
third(msg);
}
void test(char ** msg) {
*msg = malloc(5 * sizeof (char));
strcpy(*msg, "test");
printf("\nthe msg in test after is: %s\n", *msg);
change(msg);
}
int main(int argc, char** argv) {
char * msg;
test(&msg);
printf("\nthe msg back in main is: %s", msg);
free(msg); // Deallocate memory ONLY when you don't need it anymore
msg = NULL; // Good practice, set to NULL freed pointer to inform that no more memory are allocated
}
忘记那个程序吧,它的错误太多了:
- 您不需要多级间接寻址。两层就够了。如果该函数需要更改地址,只需将指针传递给下一个函数即可。
- 您尝试在字符串初始化之前打印它。
- 您在释放字符串后尝试使用它。
- 您在不清除旧内容的情况下重复调用 malloc 造成了内存泄漏。请改用 realloc。
- 您分配的内存量不正确,因此数组不够大,无法容纳您将 strcpy 写入其中的字符串。另请注意,您需要为空终止符分配足够的空间。
等等。这是一个固定版本:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void third(char** msg) {
const char str[] = "third";
*msg = realloc(*msg, sizeof(str));
printf("the msg in third is :%s\n", *msg);
strcpy(*msg, str);
printf("the msg in third after is: %s\n", *msg);
}
void change(char** msg) {
const char str[] = "change";
*msg = realloc(*msg, sizeof(str));
printf("the msg in change is :%s\n", *msg);
strcpy(*msg, str);
printf("the msg in change after is: %s\n", *msg);
third(msg);
}
void test(char** msg) {
const char str[] = "test";
*msg = malloc(sizeof(str));
printf("the msg in test is just garabage at this point, no need to print it.\n");
strcpy(*msg, str);
printf("the msg in test after is: %s\n", *msg);
change(msg);
}
int main(int argc, char** argv) {
char* msg;
test(&msg);
printf("the msg back in main is: %s\n", msg);
free(msg);
}
我正在尝试理解指针,我有这个简单的例子
void third(char ****msg) {
***msg = malloc(5 * sizeof (char));
printf("\nthe msg in third is :%s ", ***msg);
strcpy(***msg, "third");
printf("\nthe msg in third after is: %s", ***msg);
// free(***msg);
}
void change(char***msg) {
**msg = malloc(5 * sizeof (char));
printf("\nthe msg in change is :%s ", **msg);
strcpy(**msg, "change");
printf("\nthe msg in change after is: %s", **msg);
third(&msg);
// free(**msg);
}
void test(char ** msg) {
*msg = malloc(5 * sizeof (char));
printf("\n the msg in test is: %s", *msg);
strcpy(*msg, "test");
printf("\nthe msg in test after is: %s\n", *msg);
change(&msg);
free(*msg);
}
int main(int argc, char** argv) {
char * msg;
test(&msg);
printf("\nthe msg back in main is: %s", msg);
}
我可以说它工作正常,但是你能告诉我什么时候以及如何释放分配的内存吗,因为如果我从函数更改和第三个和 运行 中删除 // 我是有错误。有没有办法在每个函数的第一个 print 语句中获取消息的内容 - 请参阅 otuput:
the msg in test is:
the msg in test after is: test
the msg in change is :0��
the msg in change after is: change
the msg in third is :P��
the msg in third after is: third
the msg back in main is:
有没有办法让 msg 发生变化:测试然后 第三个消息是:更改
在现实生活中,尽量避免使用"star"(即间接数)。您的代码还有几个问题涉及 undefined behavior (UB)
void third(char ****msg) {
***msg = malloc(5 * sizeof (char));
printf("\nthe msg in third is :%s ", ***msg);// Don't do that, ***msg is not intialize => UB
strcpy(***msg, "third"); // Don't do that => ***msg has 5 bytes, and you copy 6 char => UB
printf("\nthe msg in third after is: %s", ***msg);
// free(***msg);
}
void change(char***msg) {
**msg = malloc(5 * sizeof (char));
printf("\nthe msg in change is :%s ", **msg);// Don't do that, **msg is not intialize => UB
strcpy(**msg, "change"); // Don't do that => **msg has 5 bytes, and you copy 7 char => UB
printf("\nthe msg in change after is: %s", **msg);
third(&msg);
// free(**msg);
}
void test(char ** msg) {
*msg = malloc(5 * sizeof (char));
printf("\n the msg in test is: %s", *msg); // Don't do that, *msg is not intialize => UB
strcpy(*msg, "test");
printf("\nthe msg in test after is: %s\n", *msg);
change(&msg);
free(*msg);
}
int main(int argc, char** argv) {
char * msg;
test(&msg);
printf("\nthe msg back in main is: %s", msg); //UB => you use freed variable
}
改正了这个UB的多个来源后,它仍然是一个糟糕的设计:使用free
函数
根据您使用...的指针这一事实,当您在函数内部执行 malloc
时,您还修改了调用者的指针。试试 运行 这个看看:
void first(char **t)
{
*t = malloc(5*sizeof(char));
}
int main(int argc, char * argv[])
{
char * t = NULL;
printf("%p\n", t);
first(&t);
printf("%p\n", t);
return 0;
}
它产生 (demo):
(nil) 0x995f008 (or another address)
因此,当您在 test
中释放时,您释放了在 third
最后,评论里已经说了,2星就够了:
void third(char **msg) {
free(*msg); // Free before allocate and change address stored in pointer
*msg = malloc(6 * sizeof (char));
strcpy(*msg, "third");
printf("\nthe msg in third after is: %s", *msg);
}
void change(char **msg) {
free(*msg); // Free before allocate and change address stored in pointer
*msg = malloc(7 * sizeof (char));
strcpy(*msg, "change");
printf("\nthe msg in change after is: %s", *msg);
third(msg);
}
void test(char ** msg) {
*msg = malloc(5 * sizeof (char));
strcpy(*msg, "test");
printf("\nthe msg in test after is: %s\n", *msg);
change(msg);
}
int main(int argc, char** argv) {
char * msg;
test(&msg);
printf("\nthe msg back in main is: %s", msg);
free(msg); // Deallocate memory ONLY when you don't need it anymore
msg = NULL; // Good practice, set to NULL freed pointer to inform that no more memory are allocated
}
忘记那个程序吧,它的错误太多了:
- 您不需要多级间接寻址。两层就够了。如果该函数需要更改地址,只需将指针传递给下一个函数即可。
- 您尝试在字符串初始化之前打印它。
- 您在释放字符串后尝试使用它。
- 您在不清除旧内容的情况下重复调用 malloc 造成了内存泄漏。请改用 realloc。
- 您分配的内存量不正确,因此数组不够大,无法容纳您将 strcpy 写入其中的字符串。另请注意,您需要为空终止符分配足够的空间。
等等。这是一个固定版本:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void third(char** msg) {
const char str[] = "third";
*msg = realloc(*msg, sizeof(str));
printf("the msg in third is :%s\n", *msg);
strcpy(*msg, str);
printf("the msg in third after is: %s\n", *msg);
}
void change(char** msg) {
const char str[] = "change";
*msg = realloc(*msg, sizeof(str));
printf("the msg in change is :%s\n", *msg);
strcpy(*msg, str);
printf("the msg in change after is: %s\n", *msg);
third(msg);
}
void test(char** msg) {
const char str[] = "test";
*msg = malloc(sizeof(str));
printf("the msg in test is just garabage at this point, no need to print it.\n");
strcpy(*msg, str);
printf("the msg in test after is: %s\n", *msg);
change(msg);
}
int main(int argc, char** argv) {
char* msg;
test(&msg);
printf("the msg back in main is: %s\n", msg);
free(msg);
}