首页 > 解决方案 > 当我在 C 中 malloc 另一个字符串时,字符串发生了变化

问题描述

我目前正在制作外壳。我想将一个简单的字符串分成一个二维数组。起初它工作得很好,但现在我有一个奇怪的问题:我的简单字符串“str”在我 malloc 任何东西后发生了变化。例如,如果我创建一个新数组,例如

char *tmp = malloc(sizeof(char) * 15));

然后 my str, which was"ls -l"将变成" OO"or " 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;
}

我期望的是,在函数try_this()中,如果我str的东西很大,"ls -l Makefile"那么两个my_putstr(str)调用都会打印同样的东西,但它们不会。

标签: carraysmalloc

解决方案


关于对函数的调用,尚不清楚您在谈论什么my_putstr(str),因为该函数和对它的任何调用都没有出现在您提供的代码中。不过,我可以肯定地说,您的内存分配代码是有问题的,并且至少部分不正确。考虑一下:

    char **map = malloc(nb_rows * sizeof(*map + 1));

. 那里到底+ 1有什么意义?请注意,*map有类型char *,因此也有*map + 1sizeof运算符根据其操作数的类型计算结果,因此您的sizeof表达式计算的值与sizeof(*map). 我猜你可能想要

    char **map = malloc((nb_rows + 1) * sizeof(*map));

nb_rows + 1,它为指针保留空间。

同样,这...

    map[i] = malloc(nb_cols * sizeof(**map + 1));

...没有做你可能想要的。要为每个字符串的终止符保留空间,最好写成

    map[i] = malloc((nb_cols + 1) * sizeof(**map));

. 但是由于这段代码是特定于字符串的,并且根据定义char,a 的大小是 1 ,所以我自己实际上会这样写:

    map[i] = malloc(nb_cols + 1);

您没有为数据保留足够的空间,看到内存损坏也就不足为奇了。

还要注意,检查内存分配失败(在这种情况下malloc()返回一个空指针)并在它发生时适当地处理它对于健壮的代码是必不可少的。请养成将其作为例行公事的习惯,尽管不这样做可能不会导致您询问的特定问题。


推荐阅读