当我在C中malloc另一个字符串时,字符串会发生变化

当我在C中malloc另一个字符串时,字符串会发生变化,c,arrays,malloc,C,Arrays,Malloc,我现在正在做一个贝壳。我想把一个简单的字符串分割成一个二维数组。起初它工作得很好,但现在我遇到了一个奇怪的问题:我的简单字符串str在malloc任何东西后都会发生变化。例如,如果我创建一个新数组,如 char *tmp = malloc(sizeof(char) * 15)); 然后我的str,也就是ls-l,会变成类似OO或A的东西 我已经尝试过改变malloc的大小,但是它并没有解决问题,尽管它确实让str改变了。她是我的密码: char **mem_alloc_2d_array(int

我现在正在做一个贝壳。我想把一个简单的字符串分割成一个二维数组。起初它工作得很好,但现在我遇到了一个奇怪的问题:我的简单字符串str在malloc任何东西后都会发生变化。例如,如果我创建一个新数组,如

char *tmp = malloc(sizeof(char) * 15));
然后我的str,也就是ls-l,会变成类似OO或A的东西

我已经尝试过改变malloc的大小,但是它并没有解决问题,尽管它确实让str改变了。她是我的密码:

char **mem_alloc_2d_array(int nb_rows, int nb_cols) {
    char **map = malloc(nb_rows * sizeof(*map + 1));

    for (int i = 0; i < nb_rows; i++) {
        map[i] = malloc(nb_cols * sizeof(**map + 1));
    }
    return map;
}

int what_is_x(char const *str) {
    int x = 2;

    for (int i = 0; str[i] != '\0'; i++) {
        if (str[i] == ' ')
            x++;
    }
    return x;
}

char **try_this(char const *str) {
    int size = my_strlen(str);
    int x = what_is_x(str);
    char **words = mem_alloc_2d_array(x, size);

    return words;
}

char **my_str_to_wordtab(char *str) {
    int j = 0;
    int i = 0;
    char **words = try_this(str);

    if (str[0] == '\n' || str[0] == '\r')
        words[0] = NULL;
    for (; str[i] == ' ' || str[i] == '\t'; i++);
    for (int x = 0; str[i] != '\n'; i++, x++) {
        if (str[i] == ' ' || str[i] == '\t') {
            words[j][x] = '\0';
            j++;
            x = 0;
            while (str[i] == ' ' || str[i] == '\t')
                i++;
        }
        words[j][x] = str[i];
    }
    j++;
    words[j] = (char *)0;
    return words;
}

我所期望的是,在函数中试试这个,如果我的str像ls-l Makefile一样大,那么我的两个putstr调用将打印相同的东西,但它们不会打印相同的东西。

关于函数my putstr的调用,不清楚您在谈论什么,因为您所展示的代码中既没有该函数也没有对它的任何调用。然而,我可以肯定地说,您的内存分配代码是错误的,至少部分是错误的。考虑这一点:

    char **map = malloc(nb_rows * sizeof(*map + 1));
。这里+1的意义到底是什么?请注意,*map有char*类型,因此,*map+1也有char类型。sizeof运算符根据其操作数的类型计算结果,因此sizeof表达式计算的值与sizeof*映射的值相同。我猜你可能想要

    char **map = malloc((nb_rows + 1) * sizeof(*map));
,它为nb_行+1个指针保留空间

同样地,这

    map[i] = malloc(nb_cols * sizeof(**map + 1));
。。。不做你可能想做的事。要为每个字符串保留一个终止符的空间,最好将其写成

    map[i] = malloc((nb_cols + 1) * sizeof(**map));
。但是,由于这段代码是特定于字符串的,并且字符的大小定义为1,所以我自己会这样写:

    map[i] = malloc(nb_cols + 1);
如果没有为数据保留足够的空间,那么内存损坏也就不足为奇了


还要注意的是,检查内存分配失败(在这种情况下malloc返回空指针)并在出现空指针时进行适当处理对于健壮的代码来说至关重要。一定要养成这样做的习惯,这是例行公事,尽管不这样做可能不会导致您所问的特定问题。

如果您看到的行为似乎不符合语言要求,尤其是与动态内存分配有任何关联,那么,您的程序执行未定义行为的可能性很高。有关内存滥用的问题通常可以通过Valgrind等内存使用分析器进行分析。您需要给出答案,否则我们无法帮助您,我们在mem_alloc_2d_数组中没有魔法水晶球,sizeof*map+1与sizeof*map或sizeofchar*相同,sizeof**map+1是sizeof**map/sizeofchar。不清楚+1应该完成什么。@molbdnilo:Phew,你完全正确,临时大脑圈…:}您可能应该只分配一个指针数组。然后根据需要按字符串分配房间。二维字符数组似乎不正确。