Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C字符数组,指针,malloc,free_C_Pointers_Char_Malloc_Free - Fatal编程技术网

C字符数组,指针,malloc,free

C字符数组,指针,malloc,free,c,pointers,char,malloc,free,C,Pointers,Char,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 ch

我试图理解指针,我有一个简单的例子

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);
}
我可以说它工作得很好,但是你能告诉我何时以及如何释放分配的内存吗?因为如果我删除//from函数change和third并运行它,我就会出错。是否有办法在每个函数的第一个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改变为:test然后
第三条消息是:在现实生活中改变,避免使用尽可能多的间接寻址。此外,您的代码还有几个问题涉及到

在纠正了UB的多个来源之后,它仍然是一个糟糕的设计:使用自由函数

根据您使用的指针的事实。。。在函数中执行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;
}
它产生:

所以,当您在测试中释放内存时,您将释放第三个测试中分配的内存

最后,正如评论中已经提到的,只有两颗星就足够了:

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);
}

简单的例子?四次首发?你不仅仅是一个三星级的程序员。哇!你是我见到的第一个四星C程序员!你知道成为一名三星级的C程序员已经不是一种恭维了,是吗?@SouravGhosh:什么是树星程序员?有人住在树上吗-@Olaf编辑过…但这是真的,如果我继续这样写代码,避免维护者的最安全的地方就是一个树屋-删除更改和第三个,从一开始就开始分析。好的,我理解。那么如何释放内存呢。“免费考试够了吗?”@JohnRichards我想我的编辑回答了你的问题,棒极了!现在我明白了。这是否适用于其他数据类型,例如int或int[]?@JohnRichards数组的数据类型并不重要,但用作字符串的字符数组是一种特殊情况,因为它们需要以null结尾。当声明const char str[]=test时;您将得到一个由4个字符+1个空终止符组成的数组。这就是sizeofstr工作的原因。
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
}
#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);
}