Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.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
字符串不是';t在使用函数后发生变异,尽管在函数c语言中发生了变异_C_String_Pointers_Scope_Mutation - Fatal编程技术网

字符串不是';t在使用函数后发生变异,尽管在函数c语言中发生了变异

字符串不是';t在使用函数后发生变异,尽管在函数c语言中发生了变异,c,string,pointers,scope,mutation,C,String,Pointers,Scope,Mutation,快速总结-我正在测试我的函数,为此,我决定编写我自己的add_as_first()和add_as_last()函数,它们通过创建一个新的字符串数组并制作一个副本将字符添加到旧的字符串数组中,而不使用默认的c语言字符串函数。出于某种原因,每两个字符串数组中就有一个的行为与我希望的不一样。我添加了strlen()函数进行调试,我可以看到在print_文件函数中,我的字符串数组非常健康,并且随着函数的循环而不断变大。但由于某种原因,当函数结束时,其中一个字符串“res”的长度回到0,而第二个字符串“b

快速总结-我正在测试我的函数,为此,我决定编写我自己的add_as_first()和add_as_last()函数,它们通过创建一个新的字符串数组并制作一个副本将字符添加到旧的字符串数组中,而不使用默认的c语言字符串函数。出于某种原因,每两个字符串数组中就有一个的行为与我希望的不一样。我添加了strlen()函数进行调试,我可以看到在print_文件函数中,我的字符串数组非常健康,并且随着函数的循环而不断变大。但由于某种原因,当函数结束时,其中一个字符串“res”的长度回到0,而第二个字符串“body”得到了正确的变异,并且有一个应该具有的值。它们之间的区别在于,“res”是通过在print_file循环函数中使用add_as_last()函数来填充的,而“body”是通过在print_file()中的forming_list()函数中使用add_as_first()函数来填充的。知道它为什么会这样吗?它看起来像是范围问题,但考虑到“body”和“res”的使用方式大致相同,它应该正常工作

#include <stdio.h>
#include <stdlib.h> 
#include <string.h>

#define x_size 4
#define y_size 4


char* add_as_first(char *given_arr, char given_char, int check) {
    int strLen = 0;
    while (given_arr[strLen] != '\0') {
        strLen++;
    }
    char *new_arr;
    new_arr = (char*)malloc((strLen + 1 + 1) * sizeof(char));
    
    new_arr[0] = given_char;
    int i = 0;

    for (; i < strLen; i++) {
        new_arr[i + 1] = given_arr[i]; 
    }
    new_arr[i + 1] = '\0';
    if ((i + 1 + 1) != (strLen + 1 + 1)) {
        printf("WE GOT A MEMORY LEAK OUT THERE\n");
    }

    if (check != 0) {
        free(given_arr);
    }
    return new_arr;
}

char* add_as_last(char *given_arr, char given_char, int check) {
    int strLen = 0; 
    while (given_arr[strLen] != '\0') {
        strLen++;
    }
    char* newString = (char*)malloc((strLen + 1 + 1) * sizeof(char));
    int i = 0;

    for(; i < strLen; i++) {
        newString[i] = given_arr[i];
            
    }

    newString[i] = given_char;
    newString[i + 1] = '\0';
    if ((i + 1 + 1) != (strLen + 1 + 1)) {
        printf("WE GOT A MEMORY LEAK OUT THERE\n");
    }
    return newString;
}

void forming_list(int file_arr[][y_size], int i, int j, char body[]) {
    char thing = '0';
    thing = j + '0';
    body = add_as_first(body, thing, 1);
    body = add_as_first(body, ',', 1);
    thing = i + '0';
    body = add_as_first(body, thing, 1);
    body = add_as_first(body, ' ', 1);
    if ((file_arr[i][j] == 1) || (file_arr[i][j] == 5)) {
        if (j < x_size - 1) {
            forming_list(file_arr, i, j + 1, body);
        } else {
            forming_list(file_arr, i + 1, 0, body);
        }
    } else if ((file_arr[i][j] == 2) || (file_arr[i][j] == 6)) {
        if (j != 0) {
            forming_list(file_arr, i, j - 1, body);
        } else {
            forming_list(file_arr, i - 1, x_size - 1, body);
        } 
    } else if ((file_arr[i][j] == 3) || (file_arr[i][j] == 7)) {
        if (i == 0) {
            forming_list(file_arr, y_size - 1, j, body);
        } else {
            forming_list(file_arr, i - 1, j, body);
        } 
    } else if ((file_arr[i][j] == 4) || (file_arr[i][j] == 8)) {
        if (i == y_size - 1) {
            forming_list(file_arr, 0, j, body);
        } else {
            forming_list(file_arr, i + 1, j, body);
        } 
    } 
}

void print_file(int file_arr[][y_size], char *res, char *body) {
    int i = 0;
    int j = 0;
    for(i; i < y_size; i++) {
        for (j; j < x_size; j++) {
            if ((file_arr[i][j] >= 5) && (file_arr[i][j] <= 9)) {
                res = add_as_last(res, '#', 1);
            } 
            else if ((file_arr[i][j] >= 1) && (file_arr[i][j] <= 4)) {
                res = add_as_last(res, '#', 1);
                forming_list(file_arr, i, j, body); 
            } else {
                res = add_as_last(res, 'x', 1);
            }
        }
        res = add_as_last(res, '\n', 1);
        printf("Length of string = %zu \n",strlen(res));
        j = 0;
    }
}

int main()
{

    int disp[x_size][y_size] = {
    {0, 1, 8, 0},
    {0, 0, 8, 0},
    {0, 9, 6, 0},
    {0, 0, 0, 0}
};
    char *res;
    char *body;
    res = (char*)malloc((1) * sizeof(char));
    body = (char*)malloc((1) * sizeof(char));

    res[0] = '\0';
    body[0] = '\0';
    printf("Length of string = %zu \n",strlen(res));
    print_file(disp, res, body);
    printf("Length of string = %zu \n",strlen(res));
    printf("%s\n", res);
    printf("%s\n", body);
    return 0;
}
2,1 2,2 1,2 0,2 0,1//打印正确填写的“正文”字符串


为什么在我的程序完成工作后,尽管“body”和“res”的值如此相似,但“body”和“res”的值却如此不同?

您的
print\u file
函数正在修改
res
,但新指针永远不会传回main。
因此main的
res
仍然指向(长期销毁的)原始
res
,它为
strlen
(或任何其他内容)生成未定义的巴哈维奥语


您应该通过引用传递
res
指针,或者传递指向它的指针,以便修改返回到main中。

您的
print\u file
函数正在修改
res
,但新指针永远不会返回到main中。
因此main的
res
仍然指向(长期销毁的)原始
res
,它为
strlen
(或任何其他内容)生成未定义的巴哈维奥语


您应该通过引用传递
res
指针,或者传递指向它的指针,这样修改就会返回到main中。

记住,函数参数是通过值传递的。也就是说,参数的值被复制到函数参数变量中。修改此副本当然不会修改原件。考虑一下调用
打印文件(disp、res、body)
。我知道按引用传递/按值传递的差异,我知道我可以返回“res”,它会工作得很好,但我试图理解差异,为什么“body”按预期工作,以及“res”在内存中丢失?您的代码中很可能有某种未定义的行为。试着缩减你的计划(很多!),把你的计划的最小部分发挥到极致。确保它有效。然后一次添加一小部分,构建(启用详细的额外警告)和测试。当问题发生时,你可以缩小范围,只调试小的非工作位。另外,请阅读,接受SO,阅读,以及。你的问题是一堵很难阅读的文字墙。我知道我应该避免问重复的问题,但我的问题是我不知道如何表述它。如果我更熟悉C语言中的这些诡计和术语,我想我就不会费心去制造烦人的问题了。记住,函数参数是按值传递的。也就是说,参数的值被复制到函数参数变量中。修改此副本当然不会修改原件。考虑一下调用
打印文件(disp、res、body)
。我知道按引用传递/按值传递的差异,我知道我可以返回“res”,它会工作得很好,但我试图理解差异,为什么“body”按预期工作,以及“res”在内存中丢失?您的代码中很可能有某种未定义的行为。试着缩减你的计划(很多!),把你的计划的最小部分发挥到极致。确保它有效。然后一次添加一小部分,构建(启用详细的额外警告)和测试。当问题发生时,你可以缩小范围,只调试小的非工作位。另外,请阅读,接受SO,阅读,以及。你的问题是一堵很难阅读的文字墙。我知道我应该避免问重复的问题,但我的问题是我不知道如何表述它。如果我更熟悉这些恶作剧和C语言中的术语,我想我不会费心去制造烦人的问题。我是这样想的,但为什么指向“身体”的指针没有被破坏,并且工作正常?@Jermog-未定义的行为是令人讨厌的。它不必破裂。它不必工作。这不一定有道理。它不必是一致的。@Jonathan Leffler所以,我的“body”指针和“res”指针一样受到损害,我很幸运(甚至不了解真正的原因)它能工作,我应该确保“res”和“body”指针都以某种方式返回?
body
被销毁。如果你通过静态分析器运行它,你甚至会在第100行(
形成列表(file\u arr,i,j,body)
)得到一个警告,这会在空闲后使用内存;我已经足够大了,我是通过阅读K&R的书学会的(你可能不应该那样学C,那是很久以前的事了)。但我确实建议您坐下来学习一门课程或一本书来学习C内存管理。看看这段代码,感觉您的背景语言具有更自动的内存管理。你的蔑视
                  //Printing empty "res" string