不使用 malloc() 将字符串复制到另一个地址

Copy string to another address without malloc()

我(显然)正在学习 C

我不明白为什么我会使用malloc为新复制的字符串分配内存(他们在cs50内存讲座中这样做)

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

int main(){
    char *s = "Hi";
    char *t; // Why the need for char *t malloc(3) here ??
    strcpy(t,s);
    printf("%s",t); // prints "Hi"
    return 0;
}

第一个声明:char *s = "Hi"; 不需要 malloc,因为在编译时,编译器会将 s 设置为指向在内存中已经有指定位置的字符串文字。

第二个声明:char *t; 没有指定指向任何东西。您可以将 s 的内容复制到 t 中,也许一切都会起作用,但是您会将 s 的内容复制到 t 最初是的某个随机内存部分指向您的 OS 尚未分配给您的位置。最有可能导致段错误和崩溃。

这就是 malloc 所做的,它请求在堆上为您的程序分配一些字节,然后 returns 一个指向该内存起始地址的指针(如果失败则为 NULL)出于任何原因分配内存),允许您在请求成功时安全地使用它。

你在做什么叫做UB,Undefined Behavior。您应该始终为 strcpy 分配必要的内存。

事实上,您甚至没有包含 string.h,您的代码将无法运行,因为 strcpy 将是一个未定义的函数。

即使它由于某些错误而以某种方式起作用,您也总是会遇到分段错误。你只分配了 3 个字节,所有这些都被占用了。您的代码是可利用的,并且是恶意输入的安全漏洞

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

int main(void)
{
    char *e = malloc(3);

    char *b;

    strcpy(e, "Hi"); // 3 bytes

    strcpy(b, e);

    fputs(b, stdout);
}

分段错误。我们正在将 3 个字节写入 0 字节的区域。 (strcpy(b, e))

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

int main(void)
{
    char *e = "Hi";

    char *b;

    strcpy(b, e);

    fputs(b, stdout);

}

分段错误。一样的。

甚至 运行 你的代码 string.h,


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

int main(){
    char *s = "Hi";
    char *t; // Why the need for char *t malloc(3) here ??
    strcpy(t,s);
    printf("%s",t); // prints "Hi"
    return 0;
}

你猜怎么着?分段错误。

抱歉我太苛刻了,但这是 C 用户需要学习的一个非常重要的主题,因为它可能会引入安全漏洞和不愉快的编码体验。

始终验证输入,并且始终分配必要的 space。

如果您遇到段错误,最好的工具之一是 Valgrind 或 Asan。

Valgrind你得自己查,但Asan是: gcc -fsanitize=address filename -o filename -g 这将捕获所有缓冲区溢出,使您的生活更加愉快。 您必须包含 -g,它将您的代码附加到编译后的文件,这样 Asan 就可以告诉您您的程序在哪一行失败。