C动态复制字符串

标签 c string malloc

<分区>


我有两个版本的 C 代码。第一个有效,但第二个无效。
第二个的输出是段错误,但我不知道为什么。
也许有人可以解释我的错误?我真的很感激。

这有效:

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

void stringcpy(const char*, char*);

    int main() {

        const char * original = "C is fun.";
        int size = sizeof(original) / sizeof(char*);
        copy = (char*)malloc(sizeof(char) * 11 + 1);

        stringcpy(original, copy);
        printf("%s\n", copy);

        free(copy);

        return 0;
    }

    void stringcpy(const char* original, char* copy) {

        int i;
        for(i = 0; *(original + i) != '\0'; i++) {
            *(copy + i) = *(original + i);
        }
        *(copy + i) = '\0';
    }

这行不通:

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

void stringcpy(const char*, char*);

int main() {

    const char * original = "C is fun.";

    char * copy;
    stringcpy(original, copy);
    printf("%s\n", copy);

    free(copy);

    return 0;
}

void stringcpy(const char* original, char* copy) {

    int size = sizeof(original) / sizeof(char*);
    copy = (char*)malloc(sizeof(char) * size + 1);

    int i;
    for(i = 0; *(original + i) != '\0'; i++) {
        *(copy + i) = *(original + i);
    }
    *(copy + i) = '\0';
}

最佳答案

int size = sizeof(original) / sizeof(char*);

在这里将 sizeof 应用于指针而不是数组。这不会返回它指向的字符串的大小。 strlen 是您应该在这里寻找的那个。用这个替换上面的行

int size = strlen(original); // better to use `size_t`

现在这里发生了什么——字符串文字是一个 char 数组,它退化为指向第一个元素的指针,并且正在分配该指针值——你在其上应用了 sizeof。这里没有阵法的痕迹。要获取数组可以容纳的元素数,您必须传递数组本身而不是指针。

另一件事是 C 是按值传递的 - 所以这里要保留更改,要么将指针传递给指针,要么传递从函数分配的内存地址。

sizeof(char)1 所以你不需要明确地写它 - 你可以简单地写

copy = malloc(size + 1);

代码:

stringcpy(original, &copy);

void stringcpy(const char* original, char** copy) {

    int size = strlen(original);
    *copy = malloc(size + 1);

    int i;
    for(i = 0; original[i] != '\0'; i++) {
        (*copy)[i] = original[i];
    }
    (*copy)[i] = '\0';
}

我已经通过将指针变量的地址传递给另一个函数来向您展示了问题的解决方案。或者(自己尝试)您可以从函数返回分配的内存块地址并将其分配给 copy。这也行。

编辑:如果您不允许更改函数签名,那么是的,除非您像之前在案例 1 中那样将分配的内存提供给 copy,否则这是不可能的。

实现正确行为的另一种方法是这样做

char* stringcpy(const char* original) {

    int size = strlen(original) ;
    char* copy = malloc(size + 1);

    int i;
    for(i = 0; original[i] != '\0'; i++) {
        copy[i] = original[i];
    }
    copy[i]=0;
    return copy;
}

然后像这样使用它

copy = stringcpy(original);

此答案中省略了一些内容:

  • 始终检查 malloc 的返回值 - 如果它返回 NULL,如果您检查它,您将不会取消引用它。

  • 不要将 malloc 的返回类型强制转换 - char*void* 的转换是隐式的。

  • 使用完后释放动态分配的内存。

关于C动态复制字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48587205/

相关文章:

c++ - 基于时间的通知使用的是 UTC 时间还是本地时间?

java - Python 到 Java 代码 : String. 在 java 中进行编码()

c - 需要知道如何在 c 中按空格解析单词。还需要知道我是否正确分配内存?

c - 我是否在我的结构指针上正确地调用了 free() ?

将单个 malloc 切 block /分割/打包成具有不同类型/对齐方式的多个数组的规范方法?

c - C 中的错误 malloc

c++ - 像 native Windows 应用程序中的 FireFox 中的选项卡控件

c - 从包含数组的文件中存储/检索特定数组

c - 从所有数组元素打印字符串

c++ - 为什么 sizeof(str.substr(0,3).c_str()) 给我 8?